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个数据库中都没有数据,图如下:
具体代码:
代码运行成功截图:
代码故意抛出异常:
代码运行失败:
失败后2个数据库中没有插入(事务回滚了):
参考:
http://blog.csdn.net/super_scan/article/details/39400719
相关推荐
3. **两阶段提交(2PC)**:这是一种经典的分布式事务解决方案,包括准备阶段和提交阶段。所有参与者首先在准备阶段进行预提交,然后在提交阶段根据所有参与者的结果决定是否正式提交。然而,2PC存在单点故障、阻塞...
1. 电子商务系统:分布式事务可以应用于电子商务系统中的订单处理、库存管理和支付系统等。 2. 云计算平台:分布式事务可以应用于云计算平台中的资源管理、任务调度和数据存储等。 3. 微服务架构:分布式事务可以...
MySQL的XA实现允许应用程序通过两阶段提交(2PC)协议来确保分布式事务的一致性。 #### 七、两阶段提交(2PC) 两阶段提交是实现分布式事务的核心机制。其主要步骤如下: 1. **准备阶段(Prepare Phase)**:事务管理...
还有XA以及两阶段提交,并通过实例演示了使用JTA,通过两阶段提交,实现多数据源的事务实现。... 4-1 Spring事务机制_基本接口 4-2 Spring事务机制_实现 4-3 Jpa事务实例 4-4 Jms事务原理 4-5 Jms-session事务实例 4...
分布式事务的解决方案通常基于最终一致性,比如两阶段提交(2PC)和三阶段提交(3PC)协议。这些协议在处理分布式事务时,能够保证系统在面临网络分区或节点故障时仍然能按照预定的方式处理事务。 在分布式事务的控制...
一种是基于2PC(两阶段提交)的算法,它通过协调者协调各个参与者节点,在第一阶段准备操作,并在第二阶段提交或回滚,从而保证分布式系统的一致性。然而,这种方法牺牲了可用性,特别是在网络分区的情况下,系统...
在MySQL中实现分布式事务通常使用两阶段提交协议(2PC)。事务的第一阶段是准备阶段,所有参与者节点准备提交事务,并将事务状态锁定到一个预备状态。第二阶段是提交阶段,如果所有参与者都准备好了,事务管理器则...
- **两阶段提交(Two-Phase Commit, 2PC)**:协调者和参与者两阶段交互,决定是否提交或回滚所有事务。这种方法简单但效率低,容易造成阻塞,并且在协调者失败时可能导致死锁。 - **三阶段提交(Three-Phase Commit, ...
3. **2PC(两阶段提交)协议**:这是最早的分布式事务处理协议,包括准备阶段和提交阶段。虽然简单,但存在阻塞、单点故障等问题。 4. **3PC(三阶段提交)协议**:为了解决2PC的问题,3PC引入了预提交阶段,降低了...
具体来说,XA 协议通过两阶段提交(Two-Phase Commit, 2PC)实现这一点,其中包含准备(Prepare)和提交(Commit)阶段。 #### 2. MySQL XA 事务的特点 ##### 2.1 跨数据库实例支持 MySQL 的 XA 事务支持在不同的 ...
它维护全局事务的状态,并通过两阶段提交(2PC)协议确保事务的一致性。 2. **服务资源管理器 (Resource Manager, RM)**:每个参与分布式事务的服务都需要实现RM接口,用于管理本地事务,与GTC进行通信,报告本地...
X/Open分布式事务处理模型(XA)使用两阶段提交协议来保证分布式事务的ACID属性(原子性、一致性、隔离性、持久性)。然而,XA协议的同步协商特征使得系统整体可用性降低,性能下降,并且在微服务架构中并不适用。 ...
此外,JTA还支持两阶段提交(2PC)协议,以协调不同资源的提交过程,确保全局一致性。 总之,JTA分布式事务的示例代码展示了如何在Java环境中处理跨多个数据源的事务,保证在分布式系统中的数据一致性。理解和掌握...
- **两阶段提交(2PC)**:由预备阶段和提交阶段组成,协调者与参与者共同决定事务是否提交,存在协调者单点故障和长时间阻塞的问题。 - **TCC(Try-Confirm-Cancel)**:每个服务都有尝试操作、确认操作和取消...