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 ...
随机推荐
- 绘制地图其实并不难!如何绘制地图?看看Smartbi的制作方法
数据地图是一种图形化的数据资产管理工具,它提供了多层次的图形化展现,并具备各种力度的控制能力,满足业务使用.数据管理.开发运维不同应用场景的图形查询和辅助分析需求.长期以来,很多职场人士都希望能在自己 ...
- .Net Core之JWT授权
一.什么是JWT 文章参考:https://www.leo96.com/article/detail/55 JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义 了一种紧凑且自包含 ...
- Java课程设计---创建数据库工具类
1.传统的数据库操作 package com.java.mysql; import java.sql.Connection; import java.sql.DriverManager; import ...
- Codeforces Round #726 (Div.2) A-E1 题解
A. Arithmetic Array 题目大意:一串数,求添加多少个非负整数后平均值为1 代码: //CF726A #include<bits/stdc++.h> using names ...
- docker:打包node+npm+pm2运行环境镜像
最近公司有一个外包项目需要在不能连外网的情况下部署node项目到甲方公司内部.直接使用node官网的安装包可以获得node运行环境,但像pm2这种工具要离线装就会比较费劲,所以最终选择了使用docke ...
- WPS:Excel删除指定行以后的所有行
首先定位到你的1000行,然后选中第1000行按住Shift,再同时按住Ctrl加向下的方向键,最后删除即可了.
- JZ-056-删除链表中重复的结点
删除链表中重复的结点 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4-> ...
- linux文本编辑工具
文本编辑工具VIM vim 主要有三种工作模式,分别是命令模式.插入模式和编辑模式,输入 vim 文件名 我们可以进入命令模式,输入字符 i或者a或者o我们可以进入插入模式,进入插入模式之后我们可以进 ...
- ELKB-ElasticSearch-Logstash-Kibana-beats 个人理解
先说一下ELK,E是ElasticSearch,L是Logstash,K是Kibana,还有一个Beats.按照从采集到展示的顺序介绍下各个组件的作用. 1.Beats Beats 是一个免费且开放的 ...
- 记录一次docker容器内修改my.cnf配置文件max_allowed_packet参数的过程
1. 问题背景 在一次新版本功能开发完毕,配合测试的过程中,测试反馈某个XxlJob定时任务一直执行失败,在分析了日志之后,找到了报错的原因: Packet for query is too larg ...