• 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 <!--数据源1:mySQL数据库-->
     2   <bean id="dataSourceMySQL" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
     3         <property name="jdbcUrl" value="${jdbcUrl1}"></property>
     4         <property name="driverClass" value="${driverClass1}"></property>
     5         <property name="user" value="${user1}"></property>
     6         <property name="password" value="${password1}"></property>
     7         <property name="initialPoolSize" value="${initialPoolSize1}"></property>
     8         <property name="minPoolSize" value="3"></property>
     9         <property name="maxPoolSize" value="${maxPoolSize1}"></property>
    10         <property name="acquireIncrement" value="3"></property>
    11         <property name="maxIdleTime" value="1800"></property>
    12     </bean>
    13 <!--数据源2:SQLServer数据库-->
    14     <bean id="dataSourceSQLServer" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
    15         <property name="jdbcUrl" value="${jdbcUrl2}"></property>
    16         <property name="driverClass" value="${driverClass2}"></property>
    17         <property name="user" value="${user2}"></property>
    18         <property name="password" value="${password2}"></property>
    19         <property name="initialPoolSize" value="${initialPoolSize2}"></property>
    20         <property name="minPoolSize" value="3"></property>
    21         <property name="maxPoolSize" value="${maxPoolSize2}"></property>
    22         <property name="acquireIncrement" value="3"></property>
    23         <property name="maxIdleTime" value="1800"></property>
    24     </bean>

          2、配置两个SessionFactory对象,都是org.springframework.orm.hibernate3.LocalSessionFactoryBean类的对象。

     1   <bean id="mySQLSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="false">
     2         <property name="dataSource" ref="dataSourceMySQL"/>
     3         <property name="hibernateProperties">
     4             <props>
     5                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
     6                 <prop key="hibernate.connection.release_mode">after_transaction</prop>
     7                 <prop key="hibernate.show_sql">true</prop>
     8                 <prop key="hibernate.format_sql">true</prop>
     9                 <prop key="javax.persistence.validation.mode">none</prop> 
    10             </props>
    11         </property>
    12         <property name="mappingLocations">
    13             <list>
    14                 <value>classpath:edu/cau/warning/entity/*.hbm.xml</value>
    15                 <value>classpath:edu/cau/base/entity/*.hbm.xml</value>6 17             </list>
    18         </property>
    19     </bean>21     <bean id="sQLServerSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="default">
    22         <property name="dataSource" ref="dataSourceSQLServer"/>
    23         <property name="hibernateProperties">
    24             <props>
    25                 <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
    26                 <prop key="hibernate.show_sql">true</prop>
    27                 <prop key="hibernate.format_sql">true</prop>
    28                 <prop key="javax.persistence.validation.mode">none</prop> 
    29             </props>
    30         </property>
    31         <property name="mappingLocations">
    32             <list>35                 <value>classpath:edu/cau/base/entity/*.hbm.xml</value>
    36                 <value>classpath:edu/cau/diagnosis/entity/*.hbm.xml</value>
    38             </list>
    39         </property>
    40     </bean>

          3、SessionFactory配置,DynamicSessionFactoryImpl类是个什么鬼请参考文章开头大神的文章。

    1 <bean id="sessionFactory" class="edu.cau.common.dbaccess.impl.DynamicSessionFactoryImpl">
    2     <property name="defaultTargetSessionFactory" ref="sQLServerSessionFactory"></property>
    3         <property name="targetSessionFactorys">
    4             <map>
    5                 <entry value-ref="mySQLSessionFactory" key="mySql"></entry>
    6                 <entry value-ref="sQLServerSessionFactory" key="sqlServer"></entry>
    7             </map>
    8         </property>
    9  </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>
  • 相关阅读:
    2.操作系统基础
    6.Linux基础3
    DRAM 内存介绍(一)
    131127新的一天
    Java中的super关键字何时使用
    JAVA的引用类型变量(C/C++中叫指针)
    System.out.println()的含义
    Java面试题
    HTML基础知识
    子域名查找
  • 原文地址:https://www.cnblogs.com/lyr-notebook/p/5843341.html
Copyright © 2020-2023  润新知