【Spring之事务底层源码解析,持续更新中~~~】

文章目录

  • 一、@EnableTransactionManagement工作原理
  • 二、Spring事务基本执行原理
  • 三、Spring事务传播机制与分类
  • 四、Spring事务强制回滚
  • 五、TransactionSynchronization
  • 六、Spring事务详细执行流程

一、@EnableTransactionManagement工作原理

开启Spring事务本质上就是增加了一个Advisor,但我们使用@EnableTransactionManagement注解来开启Spring事务是,该注解代理的功能就是向Spring容器中添加了两个Bean:

  1. AutoProxyRegistrar
  2. ProxyTransactionManagementConfiguration
    AutoProxyRegistrar主要的作用是向Spring容器中注册了一个InfrastructureAdvisorAutoProxyCreator的Bean。 而InfrastructureAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,所以这个类的主要作用就是开启自动代理的作用,也就是一个BeanPostProcessor,会在初始化后步骤中去寻找Advisor类型的Bean,并判断当前某个Bean是否有匹配的Advisor,是否需要利用动态代理产生一个代理对象。ProxyTransactionManagementConfiguration是一个配置类,它又定义了另外三个bean:
  3. BeanFactoryTransactionAttributeSourceAdvisor:一个Advisor
  4. AnnotationTransactionAttributeSource:相当于BeanFactoryTransactionAttributeSourceAdvisor中的Pointcut
  5. TransactionInterceptor:相当于BeanFactoryTransactionAttributeSourceAdvisor中的Advice
    AnnotationTransactionAttributeSource就是用来判断某个类上是否存在@Transactional注解,或者判断某个方法上是否存在@Transactional注解的。TransactionInterceptor就是代理逻辑,当某个类中存在@Transactional注解时,到时就产生一个代理对象作为Bean,代理对象在执行某个方法时,最终就会进入到TransactionInterceptor的invoke()方法。

二、Spring事务基本执行原理

一个Bean在执行Bean的创建生命周期时,会经过InfrastructureAdvisorAutoProxyCreator的初始化后的方法,会判断当前当前Bean对象是否和BeanFactoryTransactionAttributeSourceAdvisor匹配,匹配逻辑为判断该Bean的类上是否存在@Transactional注解,或者类中的某个方法上是否存在@Transactional注解,如果存在则表示该Bean需要进行动态代理产生一个代理对象作为Bean对象。该代理对象在执行某个方法时,会再次判断当前执行的方法是否和
BeanFactoryTransactionAttributeSourceAdvisor匹配,如果匹配则执行该Advisor中的TransactionInterceptor的invoke()方法,执行基本流程为:

  1. 利用所配置的PlatformTransactionManager事务管理器新建一个数据库连接
  2. 修改数据库连接的autocommit为false
  3. 执行MethodInvocation.proceed()方法,简单理解就是执行业务方法,其中就会执行sql
  4. 如果没有抛异常,则提交
  5. 如果抛了异常,则回滚

三、Spring事务传播机制与分类

在开发过程中,经常会出现一个方法调用另外一个方法,那么这里就涉及到了多种场景,比如a()调用b():

  1. a()和b()方法中的所有sql需要在同一个事务中吗?
  2. a()和b()方法需要单独的事务吗?
  3. a()需要在事务中执行,b()还需要在事务中执行吗?
  4. 等等情况…
    所以,这就要求Spring事务能支持上面各种场景,这就是Spring事务传播机制的由来。那Spring事务传播机制是如何实现的呢?先来看上述几种场景中的一种情况,a()在一个事务中执行,调用b()方法时需要新开一个事务执行:
  5. 首先,代理对象执行a()方法前,先利用事务管理器新建一个数据库连接a
  6. 将数据库连接a的autocommit改为false
  7. 把数据库连接a设置到ThreadLocal中
  8. 执行a()方法中的sql
  9. 执行a()方法过程中,调用了b()方法(注意用代理对象调用b()方法)
    i. 代理对象执行b()方法前,判断出来了当前线程中已经存在一个数据库连接a了,表示当前线程其实已经拥有一个Spring事务了,则进行挂起
    ii. 挂起就是把ThreadLocal中的数据库连接a从ThreadLocal中移除,并放入一个挂起资源对象中
    iii. 挂起完成后,再次利用事务管理器新建一个数据库连接b
    iv. 将数据库连接b的autocommit改为false
    v. 把数据库连接b设置到ThreadLocal中
    vi. 执行b()方法中的sql
    vii. b()方法正常执行完,则从ThreadLocal中拿到数据库连接b进行提交
    viii. 提交之后会恢复所挂起的数据库连接a,这里的恢复,其实只是把在挂起资源对象中所保存的数据库连接a再次设置到ThreadLocal中
  10. a()方法正常执行完,则从ThreadLocal中拿到数据库连接a进行提交这个过程中最为核心的是:在执行某个方法时,判断当前是否已经存在一个事务,就是判断当前线程的ThreadLocal中是否存在一个数据库连接对象,如果存在则表示已经存在一个事务了。

四、Spring事务强制回滚

正常情况下,a()调用b()方法时,如果b()方法抛了异常,但是在a()方法捕获了,那么a()的事务还是会正常提交的,但是有的时候,我们捕获异常可能仅仅只是不把异常信息返回给客户端,而是为了返回一些更友好的错误信息,而这个时候,我们还是希望事务能回滚的,那这个时候就得告诉Spring把当前事务回滚掉,做法就是:

@Transactional
public void test(){// 执行sqltry {b();} catch (Exception e) {// 构造友好的错误信息返回TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}
}
public void b() throws Exception {throw new Exception();
}

五、TransactionSynchronization

Spring事务有可能会提交,回滚、挂起、恢复,所以Spring事务提供了一种机制,可以让程序员来监听当前Spring事务所处于的状态。

@Component
public class UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Autowiredprivate UserService userService;@Transactionalpublic void test(){TransactionSynchronizationManager.registerSynchronization(newTransactionSynchronization() {@Overridepublic void suspend() {System.out.println("test被挂起了");}@Overridepublic void resume() {System.out.println("test被恢复了");}@Overridepublic void beforeCommit(boolean readOnly) {System.out.println("test准备要提交了");}@Overridepublic void beforeCompletion() {System.out.println("test准备要提交或回滚了");}@Overridepublic void afterCommit() {System.out.println("test提交成功了");}@Overridepublic void afterCompletion(int status) {System.out.println("test提交或回滚成功了");}});jdbcTemplate.execute("insert into t1 values(1,1,1,1,'1')");System.out.println("test");userService.a();}@Transactional(propagation = Propagation.REQUIRES_NEW)public void a(){TransactionSynchronizationManager.registerSynchronization(newTransactionSynchronization() {@Overridepublic void suspend() {System.out.println("a被挂起了");}@Overridepublic void resume() {System.out.println("a被恢复了");}@Overridepublic void beforeCommit(boolean readOnly) {System.out.println("a准备要提交了");}@Overridepublic void beforeCompletion() {System.out.println("a准备要提交或回滚了");}@Overridepublic void afterCommit() {System.out.println("a提交成功了");}@Overridepublic void afterCompletion(int status) {System.out.println("a提交或回滚成功了");System.out.println("a提交或回滚成功了");}});jdbcTemplate.execute("insert into t1 values(2,2,2,2,'2')");System.out.println("a");}
}

六、Spring事务详细执行流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/195666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jsp高校教师调课管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 高校教师调课管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysq…

洗浴按摩店服务预约管理系统会员小程序效果如何

洗浴按摩是线下服务需求度较高的行业,如今互联网趋势下,传统线下实体店面临多重经营痛点,需要商家转而线上管理及赋能客户消费、完善订单流程,多平台宣传让目标客户触达。 接下来让我们看看通过【雨科】平台搭建洗浴按摩店管理系…

【云原生之Docker实战】Docker环境下部署WPS Office网页版

【云原生之Docker实战】Docker环境下部署WPS Office网页版 一、WPS Office网页版介绍1.1 WPS Office网页版简介1.2 WPS Office网页版特点二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版…

22款奔驰GLE450升级香氛负离子 车载香薰功能

相信大家都知道,奔驰自从研发出香氛负离子系统后,一直都受广大奔驰车主的追捧,香氛负离子不仅可以散发出清香淡雅的香气外,还可以对车内的空气进行过滤,使车内的有害气味通过负离子进行过滤,达到车内保持清…

【C#】读取ini配置文件的内容

一、编写ini配置文件 ini文件时初始化文件,通常是系统配置文件所采用的存储格式。ini文件有自己的固定格式,是由若干个“节”(section)组成,每个节由若干个“键”(key)组成,每个key…

独孤思维:赚钱是马拉松长跑,中途放弃的都是穷b

赚钱就是一场永不停歇的马拉松长跑,中途放弃的都是穷b。 百分之百。 如果把你的一生设定为万里长跑。 开始100米是出身,家庭。 中间100米是上学,上班。 后9万9千800米是你自己。 什么意思? 出身和家庭,不是由你…

HttpSession的创建及使用

1.HttpSession对象的特点 HttpSession保存在服务器 HttpSession使用Key与Value结构存储数据 HttpSession的Key是字符串类型,Value则是Object类型 HttpSession存储数据大小无限制 2.HttpSession对象的创建 HttpSession对象的创建是通过request.getSession()方法来创建…

$‘\r‘: command not found的解决方法

在Linux系统中,运行Shell脚本,出现了如下错误: one-more.sh: line 1: $\r: command not found出现这样的错误,是因为Shell脚本在Windows系统编写时,每行结尾是\r\n,而在Linux系统中行每行结尾是\n&#xf…

37、红外遥控红外遥控电机调速

红外遥控 main.c #include <REGX52.H> #include "Delay.h" #include "LCD1602.h" #include "IR.h"unsigned char Num; unsigned char Address; unsigned char Command;void main() {LCD_Init();LCD_ShowString(1,1,"ADDR CMD NUM…

【cmake】获取到某个目录下的所有子目录名

整体工程目录结构如下。现打算获取到vac目录下的所有子目录名。 cmake 实现如下: # 设定要遍历的目录&#xff0c;保存到 VAC_INCLUDE_DIR 变量 set(VAC_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/vac)# 获取到当前目录下的所有文件和目录&#xff08;以相对路径的方式&#xff09;&a…

【源码篇】基于SpringBoot+thymeleaf实现的蓝天幼儿园管理系统

基于SpringBootthymeleaf实现的蓝天幼儿园管理系统 文章目录 系统说明技术选型成果展示账号地址及其他说明 系统说明 基于SpringBootthymeleaf实现的蓝天幼儿园管理系统是为幼儿园提供的一套管理平台&#xff0c;可以提高幼儿园信息管理的准确性&#xff0c;系统将信息准确无误…

Linux C语言 38-进程间通信IPC之信号

Linux C语言 38-进程间通信IPC之信号 本节关键字&#xff1a;C语言 进程间通信 信号量 semaphore 相关库函数&#xff1a;sem_init、sem_post、sem_wait、sem_destroy 提示&#xff1a;先做内容框架梳理&#xff0c;后期进行完善补充&#xff01; 什么是信号量&#xff1f; …

idea保存时自动删除不用的import

1、File->setting 2、Editor->General->Auto Import 按照操作&#xff0c;即可实现&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;

中国证券交易所有哪些

中国一共有五个证券交易所&#xff0c;分别是&#xff1a; 1、上海证券交易所。 上海证券交易所&#xff0c;简称为上交所。 ①成立时间&#xff1a;上交所成立于1990年11月26日&#xff0c;同年12月19日开业。 ②规模&#xff1a;截至2020年末&#xff0c;沪市上市公司家数…

2023年年末Java面试题

1、JDK 和 JRE 有什么区别&#xff1f; JDK&#xff08;Java Development Kit&#xff09;&#xff0c;Java开发工具包 JRE&#xff08;Java Runtime Environment&#xff09;&#xff0c;Java运行环境 JDK中包含JRE&#xff0c;JDK中有一个名为jre的目录&#xff0c;里面包含两…

讲解商品比价API使用说明

今日讲解商品比价API使用说明 商品数据分析 国内最早的比价搜索平台&#xff0c;专注于电商大数据的分析&#xff0c;有10年技术和数据沉淀。 公司自主研发的爬虫、搜索引擎、分布式计算等技术&#xff0c; 实现了对海量电商数据的及时监测、清洗和统计。 数据丰富 详细使…

内部类与Enum

内部类Iner class 最大特点&#xff1a;可以直接访问私有属性 分类&#xff1a; 1 局部内部类 &#xff08;有类名&#xff0c;外部类局部位置&#xff09;【局部内部类中变量与方法中局部变量&#xff08;是final的&#xff09;重名无法区分】&…

基于社区电商的Redis缓存架构-用户分享内容的分页列表缓存延迟构建以及异步通知缓存重建

分页列表缓存的延迟构建 首先&#xff0c;先来讲一下业务场景&#xff0c;用户会在 APP 中去分享内容&#xff0c;那么假如用户分享的是美食菜谱内容&#xff0c;在用户分享之后&#xff0c;先将这个美食菜谱的内容作为 k-v 进行缓存&#xff0c;但是呢&#xff0c;其实对于用…

交通强国添力量 无人机巡航为何备受期待?

在高速建设交通强国的过程中&#xff0c;交通运输部海事局计划完善“陆海空天”一体化水上交通运输安全保障体系。无人机巡航系统将在提升海事船舶监管和水上搜救能力方面发挥关键作用&#xff0c;以构建更为全面的监管体系。尽管已初步建立了海事监管体系&#xff0c;但仍存在…

大语言模型Prompt设计学习记录:Magic words(魔法词)的作用

文章目录 “扮演”或“成为”类指令&#xff1a;“总结”或“概述”类指令&#xff1a;“比较”或“对比”类指令&#xff1a;“解释”或“定义”类指令&#xff1a;“继续”或“接下来”类指令&#xff1a;“转换”或“改写”类指令&#xff1a; 在大语言模型中&#xff0c;Ma…