Java項目多數據源配置 (轉)


由於種種原因,有的時候可能要連接別人的數據庫,或者不同的數據庫沒法自動轉換,重構起來數據量又太大了,我們不得不在一個項目中連接多個數據源。從網上找了各種資料,只有這位大神給出的解決方案一下子就成功了。http://www.cnblogs.com/hoojo/p/dynamic_switch_sessionfactory_muliteSessionFactory.html,但是誠如博客最后所指出的,把不同數據庫的操作放在一個方法,就會出現事務的問題,這時候需要手動進行事務管理。雖然我也手動操作了數據庫,但是在每次服務器重新啟動或者用戶第一次訪問時會有session關閉的問題。會報如下錯誤:no value for key [org.hibernate.impl.sessionFactory@XXX] bound to thread[XXX],這個錯誤就是session意外關閉的意思。我一開始沒能找到合適的解決方案,只好遇到這個問題就讓程序再原樣執行一遍,這顯然是治標不治本。

  以我淺見,似乎是每一個request到達服務器,事務管理就給它一個session查詢數據庫,如果中途切換數據庫,session就會意外關閉。而添加了分布式事務管理,同一個request會再加一個查詢數據庫的session,供查詢另一個數據庫,這樣可以達到靈活切換數據庫的效果。

      后來我換了一種問法,提出“session意外關閉怎么辦?”,並找了一些關於事務管理的資料,了解到JTA技術可以解決此問題。JTA,即Java Transaction API,用於解決應用程序分布式事務處理。它可以解決在兩個或多個網絡計算機資源上訪問並且更新數據,在此用到其實還有點大材小用。

      下面是我的配置文件。這是借助了atomikos實現的分布式事務管理,要引入相關jar包。

      1、多數據源連接池配置

<!--數據源1:mySQL數據庫-->
  <bean id="dataSourceMySQL" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="jdbcUrl" value="${jdbcUrl1}"></property>
        <property name="driverClass" value="${driverClass1}"></property>
        <property name="user" value="${user1}"></property>
        <property name="password" value="${password1}"></property>
        <property name="initialPoolSize" value="${initialPoolSize1}"></property>
        <property name="minPoolSize" value="3"></property>
        <property name="maxPoolSize" value="${maxPoolSize1}"></property>
        <property name="acquireIncrement" value="3"></property>
        <property name="maxIdleTime" value="1800"></property>
    </bean>
<!--數據源2:SQLServer數據庫-->
    <bean id="dataSourceSQLServer" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
        <property name="jdbcUrl" value="${jdbcUrl2}"></property>
        <property name="driverClass" value="${driverClass2}"></property>
        <property name="user" value="${user2}"></property>
        <property name="password" value="${password2}"></property>
        <property name="initialPoolSize" value="${initialPoolSize2}"></property>
        <property name="minPoolSize" value="3"></property>
        <property name="maxPoolSize" value="${maxPoolSize2}"></property>
        <property name="acquireIncrement" value="3"></property>
        <property name="maxIdleTime" value="1800"></property>
    </bean>

   2、配置兩個SessionFactory對象,都是org.springframework.orm.hibernate3.LocalSessionFactoryBean類的對象。

<bean id="mySQLSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="false">
        <property name="dataSource" ref="dataSourceMySQL"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="javax.persistence.validation.mode">none</prop> 
            </props>
        </property>
        <property name="mappingLocations">
            <list>
                <value>classpath:edu/cau/warning/entity/*.hbm.xml</value>
                <value>classpath:edu/cau/base/entity/*.hbm.xml</value>6 17             </list>
        </property>
    </bean>21     <bean id="sQLServerSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="default">
        <property name="dataSource" ref="dataSourceSQLServer"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="javax.persistence.validation.mode">none</prop> 
            </props>
        </property>
        <property name="mappingLocations">
            <list>35                 <value>classpath:edu/cau/base/entity/*.hbm.xml</value>
                <value>classpath:edu/cau/diagnosis/entity/*.hbm.xml</value>
            </list>
        </property>
    </bean>

  3、SessionFactory配置,DynamicSessionFactoryImpl類是個什么鬼請參考文章開頭大神的文章。

<bean id="sessionFactory" class="edu.cau.common.dbaccess.impl.DynamicSessionFactoryImpl">
    <property name="defaultTargetSessionFactory" ref="sQLServerSessionFactory"></property>
        <property name="targetSessionFactorys">
            <map>
                <entry value-ref="mySQLSessionFactory" key="mySql"></entry>
                <entry value-ref="sQLServerSessionFactory" key="sqlServer"></entry>
            </map>
        </property>
 </bean>

 4、配置事務管理。

復制代碼
 1 <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
 2     <description>UserTransactionManager</description>
 3     <property name="forceShutdown">
 4         <value>true</value>
 5     </property>
 6 </bean>
 7 <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
 8     <property name="transactionTimeout" value="300"></property>
 9 </bean>
13 <bean id="myTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
14     <property name="transactionManager" ref="atomikosTransactionManager"></property>
15     <property name="userTransaction" ref="atomikosUserTransaction"></property>
16 </bean>
復制代碼

       5、配置事務通知等。

復制代碼
<!-- 事務通知 -->
<tx:advice id="txAdvice" transaction-manager="myTxManager"> <tx:attributes> <tx:method name="find*" read-only="true"/> <tx:method name="get*" read-only="true"/> <tx:method name="list*" read-only="true"/> <tx:method name="*" rollback-for="Throwable"/> </tx:attributes> </tx:advice>
復制代碼
復制代碼
<!-- aop配置被事務控制的類 -->
<aop:config>
    <aop:pointcut id="serviceOperation" expression="bean(*Service)" />
   <!-- 掃描以Service結尾的bean -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
</aop:config>
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM