Spring JTA多数据源事务管理详细教程

刚好项目要用到多数据源,在网上查找了很多资料,花了几天的时间对spring、jta 、atomikos、hibernate进行多数据源事务管理的配置。

也可以直接放在tomcat中运行,不过要用ws调用,因为没有做界面,ws入口在controller包里

下面是jta配置文件:

001 <context:annotation-config />
002     <!-- 使用注解的包路径 --> 
003     <context:component-scan base-package="com.rongli.service,com.rongli.dao,com.rongli.controller" />
004     <!-- 支持  @Transactional 标记   -->
005     <tx:annotation-driven transaction-manager="springJTATransactionManager" proxy-target-class="true"/>
006     <!-- 导入cxf配置文件 -->
007     <import resource="ws.cxf.xml"/>
008   
009     <!-- 加载properties配置文件 -->
010     <bean id="propertyConfigurer"
011         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
012         <property name="locations">
013             <list>
014                 <value>classpath:jta.jdbc.properties</value>
015             </list>
016         </property>
017     </bean>
018      
019     <!--公有数据库连接池  -->
020     <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
021         init-method="init" destroy-method="close" abstract="true">
022         <property name="xaDataSourceClassName"
023             value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
024         <property name="poolSize" value="10" />
025         <property name="minPoolSize" value="10" />
026         <property name="maxPoolSize" value="30" />
027         <!--获取连接失败重新获等待最大时间,在这个时间内如果有可用连接,将返回-->
028         <property name="borrowConnectionTimeout" value="60" />
029         <!--最大获取数据时间,如果不设置这个值,Atomikos使用默认的5分钟,
030         那么在处理大批量数据读取的时候,一旦超过5分钟,就会抛出类似 Resultset is close 的错误.-->
031         <property name="reapTimeout" value="20000" />
032         <!-- 最大空闲时间 -->
033         <property name="maxIdleTime" value="60" />
034          <!--连接回收时间-->
035         <property name="maintenanceInterval" value="60" />
036          <!--java数据库连接池,最大可等待获取datasouce的时间-->
037         <property name="loginTimeout" value="60" />
038         <property name="testQuery">
039             <value>select 1</value>
040         </property>
041     </bean>
042      
043     <!-- 客户数据库 -->
044     <bean id="rlc_cus" parent="abstractXADataSource">
045         <property name="uniqueResourceName" value="mysql/rlc_cus" />
046         <property name="xaProperties">
047             <props>
048                 <prop key="URL">${jdbc.rlc_cus.properties}</prop>
049                 <prop key="user">${jdbc.rlc.user}</prop>
050                 <prop key="password">${jdbc.rlc.password}</prop>
051                 <prop key="pinGlobalTxToPhysicalConnection">true</prop>
052             </props>
053         </property>
054     </bean>
055      
056     <!-- 系统数据库 -->
057     <bean id="rlc_sys" parent="abstractXADataSource">
058         <property name="uniqueResourceName" value="mysql/rlc_sys" />
059         <property name="xaProperties">
060             <props>
061                 <prop key="URL">${jdbc.rlc_sys.properties}</prop>
062                 <prop key="user">${jdbc.rlc.user}</prop>
063                 <prop key="password">${jdbc.rlc.password}</prop>
064                 <prop key="pinGlobalTxToPhysicalConnection">true</prop>
065             </props>
066         </property>
067     </bean>
068      
069     <!-- 公有SessionFactory配置 -->
070     <bean id="baseSessionFactory"
071         class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
072         abstract="true">
073         <property name="hibernateProperties">
074             <props>
075                 <prop key="hibernate.dialect">${hibernate.dialect}</prop>
076                 <prop key="hibernate.show_sql">${hibernate.format_sql}</prop>
077                 <prop key="hibernate.format_sql">${hibernate.show_sql}</prop>
078                 <prop key="javax.persistence.validation.mode">none</prop>
079             </props>
080         </property>
081         <!-- 自动扫描注解方式配置的hibernate类文件 -->
082         <property name="packagesToScan" value="com.rongli.bean"></property>
083     </bean>
084      
085     <!-- sessionFactory配置-->
086     <!-- customer sessionFactory -->
087     <bean id="cusSessionFactory" parent="baseSessionFactory">
088         <property name="dataSource" ref="rlc_cus" />
089     </bean>
090     <!-- system sessionFactory -->
091     <bean id="sysSessionFactory" parent="baseSessionFactory">
092         <property name="dataSource" ref="rlc_sys" />
093     </bean>
094  
095     <!-- atomikos事务管理器 -->
096     <bean id="atomikosTransactionManager"
097         class="com.atomikos.icatch.jta.UserTransactionManager"
098         init-method="init" destroy-method="close">
099         <!-- 调用终止时,强制关闭 -->
100         <property name="forceShutdown">
101             <value>true</value>
102         </property>
103     </bean>
104     <bean id="atomikosUserTransaction"
105         class="com.atomikos.icatch.jta.UserTransactionImp">
106         <property name="transactionTimeout">
107             <value>2000</value>
108         </property>
109     </bean>
110  
111      <!-- spring 事务管理器 -->
112     <bean id="springJTATransactionManager"
113         class="org.springframework.transaction.jta.JtaTransactionManager">
114         <property name="transactionManager">
115             <ref bean="atomikosTransactionManager" />
116         </property>
117         <property name="userTransaction">
118             <ref bean="atomikosUserTransaction" />
119         </property>
120     </bean>
121      
122     <!-- 用于测试,发布到服务器上时删除 -->
123     <bean id="systemServiceImpl"
124         class="com.rongli.service.impl.SystemServiceImpl">
125     </bean>

 运行截图:

原2个数据库中都没有数据,图如下:

spring JTA多数据源事务管理详细教程

 

spring JTA多数据源事务管理详细教程

具体代码:

spring JTA多数据源事务管理详细教程

spring JTA多数据源事务管理详细教程

代码运行成功截图:

spring JTA多数据源事务管理详细教程成功后数据库(乱码请忽略):

spring JTA多数据源事务管理详细教程

spring JTA多数据源事务管理详细教程

 

代码故意抛出异常:

spring JTA多数据源事务管理详细教程

代码运行失败:

spring JTA多数据源事务管理详细教程

失败后2个数据库中没有插入(事务回滚了):

spring JTA多数据源事务管理详细教程

阅读更多