Spring源码分析笔记--事务管理
核心类
InfrastructureAdvisorAutoProxyCreator
本质是一个后置处理器,和AOP的后置处理器类似,但比AOP的使用级别低。当开启AOP代理模式后,优先使用AOP的后置处理器。
AopConfigUtils:
/**
* The bean name of the internally managed auto-proxy creator.
*/
//和AOP一样都向容器注入以此为name的后置处理器,进行代理类的创建
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator"; /**
* Stores the auto proxy creator classes in escalation order.
*/
//按升级的顺序存储进行代理类创建的后置处理器
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(); /**
* Setup the escalation list.
*/
//代理创建类后置处理器升级列表,下标越大等级越高
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
源码跟踪
查看注解@EnableTransactionManagement源码,通过@Import导入TransactionManagementConfigurationSelector类,在类的重写方法中可以看到向容器注入了两个类AutoProxyRegistrar、ProxyTransactionManagementConfiguration
AutoProxyRegistrar
用于向容器中注册事务管理用的后置处理器
==》org.springframework.context.annotation.AutoProxyRegistrar#registerBeanDefinitions
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
==》org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
//此类下检查容器中是否有name为:"org.springframework.aop.config.internalAutoProxyCreator"的后置处理器bean,如果没有则注册,如果有则比较等级大小,若是等级大则对原beanDefination升级。例如:如果启用了AOP则不用升级
ProxyTransactionManagementConfiguration
配置事务管理所需的管理器、参数等
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
//类似AOP,这里创建了一个用于事务Advisor的Bean
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
return advisor;
}
//封装事务管理配置的参数,@Transactional(..)中的参数
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
//封装事务用的advice为Interceptor,并关联上了事务管理器
// TransactionInterceptor与AOP的Interceptor一样都继承自MethodInterceptor
//事务管理器主要用来控制事务,commit、rollback等
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
} }
运行时源码
运行时原理同AOP,对添加了@Transactional注解的类做代理,对被代理类的方法进行增强处理,执行一个拦截器链。跟踪进去可以发现Interceptor chain中多了一个TransactionIntercepor。通过此Interceptor在方法前开启事务,在方法后commit或rollback。

TransactionInterceptor
==》org.springframework.transaction.interceptor.TransactionInterceptor#invoke
==》 org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
// If the transaction attribute is null, the method is non-transactional.
//获取事务相关属性、管理器
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//开启一个事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//调用被代理类的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
//提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
流程梳理
1、 创建后置处理器InfrastructureAdvisorAutoProxyCreator
2、 创建TransactionInterceptor,加入interceptor chain。
3、 对指定后置处理器为InfrastructureAdvisorAutoProxyCreator的bean使用TransactionInterceptor进行事务处理。
Spring源码分析笔记--事务管理的更多相关文章
- Spring源码分析笔记--AOP
核心类&方法 BeanDefinition Bean的定义信息,封装bean的基本信息,从中可以获取类名.是否是单例.是否被注入到其他bean中.是否懒加载.bean依赖的bean的名称等. ...
- Spring源码分析之`BeanFactoryPostProcessor`调用过程
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 本文内容: AbstractApplicationContext#refresh前部分的一点小内容 ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- Spring源码分析之循环依赖及解决方案
Spring源码分析之循环依赖及解决方案 往期文章: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostPro ...
- Spring源码分析之AOP从解析到调用
正文: 在上一篇,我们对IOC核心部分流程已经分析完毕,相信小伙伴们有所收获,从这一篇开始,我们将会踏上新的旅程,即Spring的另一核心:AOP! 首先,为了让大家能更有效的理解AOP,先带大家过一 ...
- Spring 源码学习笔记11——Spring事务
Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- Spring源码分析专题 —— 阅读指引
阅读源码的意义 更深入理解框架原理,印象更深刻 学习优秀的编程风格.编程技巧.设计思想 解决实际问题,如修复框架中的bug,或是参考框架源码,结合实际业务需求编写一个独有的框架 阅读源码的方法 首先是 ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
随机推荐
- springboot页面国际化
引入依赖pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactI ...
- linux时钟校准
## 查看系统时间 date ## 查看硬件时间 hwclock ## 手动设置时间 date -s "20210507 17:55:00" ## 同步硬件时间 hwclock - ...
- Linux中查看进程与日志
转至:https://www.cnblogs.com/dengxiaoning/p/13336778.html Linux尽管使用频繁,仍然每次都还是需要到处去找相关的命令,如进程,日志之类的,既然这 ...
- Leaflet:LayerGroup、FeatureGroup
LayerGroup(Layer) Layer 用法:把一些Layer集中到一个组Group中,以便作为一个整体进行操作.如果把该Group加入到了Map中,任何从这个Group增加或者移除Layer ...
- k8s全方位监控-prometheus-alertmanager部署-配置第一条告警邮件
1.alertmanager告警插件部署 [root@VM_0_48_centos prometheus]# cat alertmanager-pvc.yaml apiVersion: v1 kind ...
- c# 表格控件SourceGrid使用总结
网上SourceGrid相关的资料很少,使用过程中做了下记录,以便日后查用 1:初始化 this.grid = new SourceGrid.Grid(); this.grid.Size = new ...
- 假如让你来设计SSL/TLS协议,你要怎么设计呢?
摘要:本文将从设计者的视角介绍如何一步步设计出一个简易版的 SSL/TLS 的过程,在文章的最后,再简单介绍 TLS 1.2 版本的工作机制,以此帮助大家对 SSL/TLS 协议的基本原理有一个更深入 ...
- SpringMVC入门一:基础知识(依赖、注解、文件上传/下载、拦截器、异常处理等)
为了使Spring可插入MVC架构,SpringFrameWork在Spring基础上开发SpringMVC框架,从而使用Spring进行WEB开发时可以选择使用Spring的SpringMVC框架作 ...
- Java使用Geotools读取shape矢量数据
作为GIS开发者而言,矢量数据是我们经常要用到的,而shape数据是矢量数据中最常用的格式,因此解析shape数据也是作为GIS软件开发人员必备的基础技能,而GeoTools无疑是Java最好用来处理 ...
- windows下后台启动PHP,Nginx,Redis(使用RunHiddenConsole)
启动命令(红色代码可选): 启动PHP RunHiddenConsole D:/phpStudy/PHPTutorial/php/php-5.6.27-nts/php-cgi.exe -b 127.0 ...