分布式事务处理两阶段提交实例

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

用框架的话只要配置好对个数据源,和工厂,公用一个JtaTransactionManager事物管理器,一个事物中有多个不同数据库操作不同数据源的时候会自动启用两阶段提交

,在加入事物标签的地方遇到任何异常就会自动回滚。

DataSourceTransactionManager是mybaits的事物管理器

HibernateTransactionManager是hibernate的事物管理器

JtaTransactionManager是分布式的事物管理器

这里的示例忘了在service加事物注解

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

没有花时间弄maven,lib的地址:https://pan.baidu.com/s/1skdIC3N

也可以直接放在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多数据源事务管理详细教程

 

 

参考:

http://blog.csdn.net/super_scan/article/details/39400719

 

猜你喜欢

转载自yuhuiblog6338999322098842.iteye.com/blog/2352391