这里是自实现XA分布式事务和
ORM框架
、spring事务框架
的整合
与Spring事务结合,分布式事务注解同普通事务@Transactional,于Spring事务AOP框架一体
如果对XA事务本身不了解,可以参考下我另一片博文 XA分布式事务全面理解
目录
整体思路:
- 事务管理器:使用
JtaTransactionManager
,自实现其依赖的事务管理器UserTransactionManager
。UserTransactionManager
中进行对分布式事务的begin、commit、rollback、事务状态等的管理,Spring会通过JtaTransactionManager
去调用自定义的事务管理器UserTransactionManager
以实现对分布式事务的管理。 - 开启XA事务:xa start。找到一个好的时机点,去开启XA事务,可以在ORM框架在获取连接对象connection时,先对xa的connection对象进行开启,再返回连接对象。
- 执行具体的DML操作:这部分ORM框架的职责,我们不需要干涉
- 关闭XA事务:xa end。需要一个时机去关闭XA事务,在ORM框架中的statement#execute()执行结束时去进行关闭end事务
以上2-4是不同数据源下的Connection对象获取时,都要进行的。
- 整个分布式事务提交:由Spring 事务框架可知,先会走到Spring的
TransactionInterceptor#invoke()
,invoke() 会对注解了@Transactional的方法进行分布式事务的begin、调用方法、异常rollback、正常commit的整体流程管理。但最终正常commit还是会走到我们自定义的JtaTransactionManager
的UserTransactionManager#commit()
方法中;若异常rollback会走到JtaTransactionManager
的UserTransactionManager#rollback()
方法中。所以这里的重点就是实现UserTransactionManager
的commit()和rollback()方法。 - commit:XA分布式事务commit和普通事务commit不同,在真正的commit之前需要先prepare拿到所有参与分布事务的RM的反馈。在所有RM的prepare成功时,再依次commit提交事务。
- rollback:若在5中,DML调用方法异常,会先进入Spring事务异常处理的rollback,再调用
UserTransactionManager
的rollback()。而分布式的rollback同普通事务的rollback()一样都是只对所有连接对象依次进行回滚操作即可。只是普通事务只是对一个数据库的连接对象的回滚,分布式事务是依次对所有的数据库连接对象进行回滚。
代码展示与解析:
这里会对上述的7个顺序的步骤分别给出一个代码的展示
Service层代码:分布式事务注解
这里分布式事务注解同Spring普通事务注解方式
@Transactional(rollbackFor = RuntimeException.class)
public Integer saveArea(ConsultConfigArea area) {
int count = mapper1.addArea(area);
int count1 = mapper2.addArea(area);
if (true){ // 这里用于抛出异常测试
System.out.println("rollback");
throw new RuntimeException("xx");
}
return count + count1;
}
- 注解了@Transactional(rollbackFor = RuntimeException.class)就是该方法使用分布式XA事务
- mapper1、mapper2的数据源对应不同数据库
JtaTransactionManager & 自定义UserTransactionManager
1. JtaTransactionManager
@Configuration
public class GlobalConfig {
@Bean
@ConditionalOnMissingBean(TransactionManager.class)
LocalUserTransactionManager localTransactionManager() t