学习 Spring 声明式事务的源码还是需要一定的基础,学起来才更加容易。
Spring 版本
spring-framework-5.2.22.RELEASE
我直接使用的是 Spring 项目源码,涉及到的 Spring 模块 spring-tx
。
@EnableTransactionManagement
开启事务管理器。ConnectionHolder
是否为 null 判断当前事务是否已开启事务。用一句话描述事务的整体流程可以这样:事务就是依赖于 Spring AOP 创建一个切面,在切面中完成事务的相关管理功能。
还有一些工具类,就不过多介绍了,认识这些类后就可以逐步深入的阅读事务的相关源码了。
事务的组件在 重点类介绍 我都提到过了。这里讲一下整体的流程,并贴图一张。
@EnableTransactionManagement
开启事务管理器,这就是事务的 入口。@EnableTransactionManagement
中有 @Import(TransactionManagementConfigurationSelector.class)
。@Import
解析类 TransactionManagementConfigurationSelector
后会注册两个 Bean 定义。
AutoProxyRegistrar
将会注册解析切面的 Bean 后置处理器。ProxyTransactionManagementConfiguration
配置类使用 @Bean
配置了事务的 切面、通知、切点,它们将会在切面解析时创建。事务的相关的切面是依赖于 Spring AOP 相关逻辑解析、创建。
AutoProxyRegistrar
注册的 Bean 后置处理器:InfrastructureAdvisorAutoProxyCreator
。InfrastructureAdvisorAutoProxyCreator
的 findCandidateAdvisors()
方法查找实现了接口 Advisor
的切面。BeanFactoryTransactionAttributeSourceAdvisor
。TransactionAttributeSourcePointcut
调用 AnnotationTransactionAttributeSource
匹配符合条件的 连接点。
findTransactionAttribute
逐层调用直到 SpringTransactionAnnotationParser.parseTransactionAnnotation
查找注解 @Transactional
。@Transactional
。AnnotationsScanner.sacn
扫描注解(还有递归,先接口、在父类)。调用逻辑仍然同 Spring AOP 一致,是一个切面被调用。
事务的相关逻辑在通知 TransactionInterceptor
的 invoke
方法开始事务的处理。
先不考虑事务嵌套的情况,主要理解单事务的情况,事务嵌套只是根据不同的 事务传播行为 切换事务的上下文。
invokeWithinTransaction
方法开始处理事务的相关逻辑,这是事务逻辑代码的入口。TransactionAttributeSource
、TransactionAttribute
,在方法 createTransactionIfNecessary
开启事务()。
ConnectionHolder
是否存在判断当前线程是否存在事务)。SuspendedResourcesHolder
。ConnectionHolder
记录到事务对象中。completeTransactionAfterThrowing
)或者正常执行提交事务(commitTransactionAfterReturning
)。