在最开始学习Spring AOP的时候,那时候只知道事务是利用AOP管理的,但是并没有翻看过源码,后来发现Spring不光可以管理关系型数据的事务。甚至可以同步管理Redis等其他数据库的事务,这是怎么做到的呢?本节我们一起探索一下Spring的事务
版本
SpringBoot 2.1.6.RELEASE
分析
首先如果我们自己写一个AOP来管理事务的话,会怎么做?
- 执行代理方法前开启事务
- 执行代理的方法
- 执行代理方法后回滚或者提交事务
- 如何实现Redis事务的同步提交和回滚?
Spring中关于事务的管理要比我们想象的复杂的多,本文只关注同步事务的实现,下面我们来看源码
TransactionAspectSupport
在翻看源码后找到这个类,事务切面支持,这个类实现了事务管理的核心逻辑,我们来看一下核心代码
我们通常在项目中会使用默认的DataSourceTransactionManager事务管理器 + 注解式事务(也就是声明式事务)
CallbackPreferringPlatformTransactionManager 是Spring提供的回调式事务管理器(用于编程式事务),这里我们不讨论。
可以看到声明式事务的处理逻辑,和我们上述分析的基本一致,那么他是在什么时候同步处理了其他数据的事务呢?继续深入源码
源码跟踪
我们以completeTransactionAfterThrowing() 这个方法为例(上图红框框),跟踪下去
可以看到,当我们异常需要回滚时,会调用 TransactionManager.rollback(),我们继续来跟踪这个方法
这里代码逻辑还是比较多的,我们只关注红框里的代码块,doRollback中只做了数据源的回滚,那么像Redis事务的提交是在哪里实现的?
我们来看一下 triggerAfterCompletion() 方法,答案马上就知道了
同步事务
TransactionSynchronizationManager 中会从ThreadLocal 中获取出当前线程中 “同步事务”接口集合 List<TransactionSynchronization>,然后接下来的操作就是遍历所有的TransactionSynchronization,执行synchronization.afterCompletion(completionStatus);
我们可以在TransactionSynchronization接口下找到一个Redis的实现
代码逻辑很简单,事务提交则Redis事务执行,否则取消Redis事务
同步事务的注册
我们RedisTemplate开启事务后,会执行到上图的debug处,RedisConnection 开启事务,并将当前Connection注册到TransactionSynchronizationManager 中,这样在triggerAfterCompletion 就可以同步的管理我们Redis的事务了