人生必须的知识就是引人向光明方面的明灯。这篇文章主要讲述老王读Spring Transaction从EnableTransactionManagement顺藤摸瓜,研究@Transactional的实现原理相关的知识,希望能为你提供帮助。
@TOC
前言Spring 对事务的封装是一个相对独立的功能,通过 spring-tx-5.3.9.jar
来进行支持。
里面的代码量也不大,我们完全可以像翻书的目录一样,浏览一下 spring-tx 的包结构和类,站在一个高的角度来审视一下 Spring 对事务的封装。
版本约定spring-tx 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)
正文浏览 spring-tx-5.3.9.jar
,我们大致可以挑出里面几个比较核心的类
文章图片
org.springframework.transaction.annotation.Transactional
org.springframework.transaction.annotation.EnableTransactionManagement
org.springframework.transaction.annotation.ProxyTransactionManagementConfigurationorg.springframework.transaction.interceptor.TransactionAspectSupport
org.springframework.transaction.interceptor.TransactionInterceptor
org.springframework.transaction.interceptor.TransactionAttributeorg.springframework.transaction.TransactionManager
org.springframework.transaction.PlatformTransactionManager
org.springframework.transaction.TransactionDefinition
org.springframework.transaction.SavepointManager
通常我们使用 Spring 的事务功能,都需要添加
@EnableTransactionManagement
来开启事务管理功能。那就从
EnableTransactionManagement
开始看起EnableTransactionManagement
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement /**
* 指定是否创建基于子类(CGLIB)的代理,而不是基于 jdk proxy 的代理。默认值为false。
* 注意: 它是一个全局设置,设置为 true 将影响所有需要代理的 Spring 托管 bean,而不仅仅是那些标记为 @Transactional 的 bean。
*/
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
可以看到,@EnableTransactionManagement 注解会引入
@Import(TransactionManagementConfigurationSelector.class)
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<
EnableTransactionManagement>
@Override
protected String[] selectImports(AdviceMode adviceMode)
switch (adviceMode)
case PROXY: // 默认是走这个分支
return new String[] AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName();
case ASPECTJ:
return new String[] determineTransactionAspectClass();
default:
return null;
private String determineTransactionAspectClass()
return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
可以看到,TransactionManagementConfigurationSelector 会引入一个配置类:
ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration 是 Spring 事务配置的核心类
ProxyTransactionManagementConfiguration——Spring 事务配置的核心类
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration // 事务 Advisor,实现 Spring 切面事务的核心
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null)
advisor.setOrder(this.enableTx.<
Integer>
getNumber("order"));
return advisor;
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource()
return new AnnotationTransactionAttributeSource();
// 事务拦截器
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource)
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null)
interceptor.setTransactionManager(this.txManager);
return interceptor;
可以看到,这里面配置了一个 Advisor(Spring AOP 中的概念)——
BeanFactoryTransactionAttributeSourceAdvisor
BeanFactoryTransactionAttributeSourceAdvisor 中设置的 Pointcut 和 Advice 分别是:
- Pointcut:
TransactionAttributeSourcePointcut
- Advice:
TransactionInterceptor
找到了 Advice,也就知道了它在 joinpoint 上执行的 AOP 拦截逻辑是什么。(即: @Transactional 的实现逻辑)
TransactionInterceptor事务拦截器,是实现 Spring 事务拦截的核心类。
public Object invoke(MethodInvocation invocation) throws Throwable
// Work out the target class: may be @code null.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<
?>
targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupports invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback()
@Override
@Nullable
public Object proceedWithInvocation() throws Throwable
return invocation.proceed();
@Override
public Object getTarget()
return invocation.getThis();
@Override
public Object[] getArguments()
return invocation.getArguments();
);
从源码中可以看到,业务方法的执行被封装在 MethodInvocation 中,事务的处理是放在
TransactionAspectSupport#invokeWithinTransaction()
方法中实现的。文章图片
TransactionAttributeSource用于获取事务元数据信息的接口。事务的元数据信息就包括: 使用的事务管理器、事务隔离级别、事务传播特性、事务超时时间、针对哪些异常进行回滚等
TransactionAttributeSource 获取到的事务元数据信息主要是提供给 TransactionInterceptor 来使用的。
TransactionAttributeSource 有多种实现,其中最常用的是
AnnotationTransactionAttributeSource
,它主要用来处理注解类的事务元数据,即: @Transactional文章图片
小结Spring 对事务的封装是一个相对独立的功能,通过 spring-tx-5.3.9.jar 来进行支持。
Spring 注解事务是通过 AOP 来实现的。具体的实现是放在
TransactionInterceptor
这个 Advice 类中。事务注解中的事务元数据信息的解析是通过
AnnotationTransactionAttributeSource
来处理的。如果本文对你有所帮助,欢迎点赞收藏!
有关 Spring 源码方面的问题欢迎留言一起交流...
公众号后台回复:下载IoC 或者 下载AOP 可以免费下载源码测试工程…
【老王读Spring Transaction从EnableTransactionManagement顺藤摸瓜,研究@Transactional的实现原理】阅读更多文章,请关注公众号: 老王学源码
文章图片
推荐阅读
- VMware安装Fedora 35 Workstation及使用体验
- 开发环境Ubuntu 中使用 VSCode 开发 C/C++ ④ ( 创建 tasks.json 编译器构建配置文件 | tasks.json 编译器构建配置文件分析 )
- JAVA容器之ArrayList集合详解
- Linux 内核 内存管理RCU 机制 ① ( RCU 机制简介 | RCU 机制的优势与弊端 | RCU 机制的链表应用场景 )
- Linux 内核线程调度示例一 ④ ( pthread_attr_init 初始化线程属性对象 | 完整代码示例 )
- Terraform与Kubernetes的体验
- Linux 内核 内存管理优化内存屏障 ④ ( 处理器内存屏障 | 八种处理器内存屏障 | 通用内存屏障 | 写内存屏障 | 读内存屏障 | 数据依赖屏障 | 强制性内存屏障
- Tomcat实战案例(yum和二进制安装)
- FTP连接的详细步骤及连接模式