一文带你看懂Spring事务!

Spring是什么?一文带你快速入门Spring 文章目录前言Spring是啥?它有啥好处Spring体系结构详解Spring目录结构和基础JAR包介绍Spring IOC容器:BeanFactory和ApplicationContextBeanFactoryApplicationContext第一个Spring程序 前言 从今天开始,怀着无比急切(操蛋)的心情开始学习Spring。我看了网上很多的大佬说,SpringBoot上手舒服一些,说Sp... 阅读详情

 

前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

Spring事务管理我相信大家都用得很多,但可能仅仅局限于一个@Transactional注解或者在XML中配置事务相关的东西。不管怎么说,日常可能足够我们去用了。但作为程序员,无论是为了面试还是说更好把控自己写的代码,还是应该得多多了解一下Spring事务的一些细节。

这里我抛出几个问题,看大家能不能瞬间答得上:

一、阅读本文需要的基础知识

阅读这篇文章的同学我默认大家都对Spring事务相关知识有一定的了解了。(ps:如果不了解点解具体的文章去阅读再回到这里来哦)

我们都知道,Spring事务是Spring AOP的最佳实践之一,所以说AOP入门基础知识(简单配置,使用)是需要先知道的。如果想更加全面了解AOP可以看这篇文章:AOP重要知识点(术语介绍、全面使用)。说到AOP就不能不说AOP底层原理:动态代理设计模式。到这里,对AOP已经有一个基础的认识了。于是我们就可以使用XML/注解方式来配置Spring事务管理。

在IOC学习中,可以知道的是Spring中Bean的生命周期(引出BPP对象)并且IOC所管理的对象默认都是单例的:单例设计模式,单例对象如果有"状态"(有成员变量),那么多线程访问这个单例对象,可能就造成线程不安全。那么何为线程安全?,解决线程安全有很多方式,但其中有一种:让每一个线程都拥有自己的一个变量:ThreadLocal

如果对我以上说的知识点不太了解的话,建议点击蓝字进去学习一番。

二、两个不靠谱直觉的例子

2.1第一个例子

之前朋友问了我一个例子:

在Service层抛出Exception,在Controller层捕获,那如果在Service中有异常,那会事务回滚吗?

// Service方法@Transactionalpublic Employee addEmployee() throws Exception {    Employee employee = new Employee("3y", 23);    employeeRepository.save(employee);    // 假设这里出了Exception    int i = 1 / 0;    return employee;}// Controller调用@RequestMapping("/add")public Employee addEmployee() {    Employee employee = null;    try {        employee = employeeService.addEmployee();    } catch (Exception e) {        e.printStackTrace();    }    return employee;}

@Transactional
public Employee addEmployee() throws Exception {

    Employee employee = new Employee("3y", 23);
    employeeRepository.save(employee);
    // 假设这里出了Exception
    int i = 1 / 0;

    return employee;
}

// Controller调用
@RequestMapping("/add")
public Employee addEmployee() {
    Employee employee = null;
    try {
        employee = employeeService.addEmployee();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return employee;

}

我第一反应:不会回滚吧。

但朋友经过测试说,可以回滚阿。(pappapa打脸)

640?wx_fmt=png
发生了运行时Exception,Spring事务管理自动回滚

看了一下文档,原来文档有说明:

By default checked exceptions do not result in the transactional interceptor marking the transaction for rollback and instances of RuntimeException and its  subclasses do

结论:如果是编译时异常不会自动回滚,如果是运行时异常,那会自动回滚!

2.2第二个例子

第二个例子来源于知乎@柳树文章,文末会给出相应的URL

我们都知道,带有@Transactional注解所包围的方法就能被Spring事务管理起来,那如果我在当前类下使用一个没有事务的方法去调用一个有事务的方法,那我们这次调用会怎么样?是否会有事务呢?

用代码来描述一下:

// 没有事务的方法去调用有事务的方法public Employee addEmployee2Controller() throws Exception {    return this.addEmployee();}@Transactionalpublic Employee addEmployee() throws Exception {    employeeRepository.deleteAll();    Employee employee = new Employee("3y", 23);    // 模拟异常    int i = 1 / 0;    return employee;}
public Employee addEmployee2Controller() throws Exception {

    return this.addEmployee();
}

@Transactional
public Employee addEmployee() throws Exception {

    employeeRepository.deleteAll();
    Employee employee = new Employee("3y", 23);

    // 模拟异常
    int i = 1 / 0;

    return employee;
}

我第一直觉是:这跟Spring事务的传播机制有关吧。

其实这跟Spring事务的传播机制没有关系,下面我讲述一下:

接下来我用图来说明一下:

640?wx_fmt=png
Spring会自动生成代理对象

显然地,我们拿到的是代理(Proxy)对象,调用addEmployee2Controller()方法,而addEmployee2Controller()方法的逻辑是target.addEmployee(),调用回原始对象(target)的addEmployee()。所以这次的调用压根就没有事务存在,更谈不上说Spring事务传播机制了。

原有的数据:

640?wx_fmt=png
原有的数据

测试结果:压根就没有事务的存在

640?wx_fmt=png
没有事务的存在
2.2.1再延伸一下

从上面的测试我们可以发现:如果是在本类中没有事务的方法来调用标注注解@Transactional方法,最后的结论是没有事务的。那如果我将这个标注注解的方法移到别的Service对象上,有没有事务?

@Servicepublic class TestService {    @Autowired    private EmployeeRepository employeeRepository;    @Transactional    public Employee addEmployee() throws Exception {        employeeRepository.deleteAll();        Employee employee = new Employee("3y", 23);        // 模拟异常        int i = 1 / 0;        return employee;    }}@Servicepublic class EmployeeService {    @Autowired    private TestService testService;    // 没有事务的方法去调用别的类有事务的方法    public Employee addEmployee2Controller() throws Exception {        return testService.addEmployee();    }}
public class TestService {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Transactional
    public Employee addEmployee() throws Exception {

        employeeRepository.deleteAll();

        Employee employee = new Employee("3y", 23);

        // 模拟异常
        int i = 1 / 0;

        return employee;
    }

}


@Service
public class EmployeeService {

    @Autowired
    private TestService testService;
    // 没有事务的方法去调用别的类有事务的方法
    public Employee addEmployee2Controller() throws Exception {
        return testService.addEmployee();
    }
}

测试结果:

640?wx_fmt=png
抛出了运行时异常,但我们的数据还是存在的!

因为我们用的是代理对象(Proxy)去调用addEmployee()方法,那就当然有事务了。

看完这两个例子,有没有觉得3y的直觉是真的水!

三、Spring事务传播机制

如果嵌套调用含有事务的方法,在Spring事务管理中,这属于哪个知识点?

在当前含有事务方法内部调用其他的方法(无论该方法是否含有事务),这就属于Spring事务传播机制的知识点范畴了。

Spring事务基于Spring AOP,Spring AOP底层用的动态代理,动态代理有两种方式:

至于为啥以上的情况不能增强,用你们的脑瓜子想一下就知道了。

值得说明的是:那些不能被Spring AOP增强的方法并不是不能在事务环境下工作了。只要它们被外层的事务方法调用了,由于Spring事务管理的传播级别,内部方法也可以工作在外部方法所启动的事务上下文中。

至于Spring事务传播机制的几个级别,我在这里就不贴出来了。这里只是再次解释“啥情况才是属于Spring事务传播机制的范畴”。

四、多线程问题

我们使用的框架可能是Hibernate/JPA或者是Mybatis,都知道的底层是需要一个session/connection对象来帮我们执行操作的。要保证事务的完整性,我们需要多组数据库操作要使用同一个session/connection对象,而我们又知道Spring IOC所管理的对象默认都是单例的,这为啥我们在使用的时候不会引发线程安全问题呢?内部Spring到底干了什么?

回想一下当年我们学Mybaits的时候,是怎么编写Session工具类?

640?wx_fmt=png
Mybatis工具类部分代码截图

没错,用的就是ThreadLocal,同样地,Spring也是用的ThreadLocal。

以下内容来源《精通 Spring4.x》

我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态的“状态性对象”采用ThreadLocal封装,让它们也成为线程安全的“状态性对象”,因此,有状态的Bean就能够以singleton的方式在多线程中工作。

我们可以试着点一下进去TransactionSynchronizationManager中看一下:

640?wx_fmt=png
全都是ThreadLocal

五、啥是BPP?

BBP的全称叫做:BeanPostProcessor,一般我们俗称对象后处理器

Spring管理Bean(或者说Bean的生命周期)也是一个常考的知识点,我在秋招也重新整理了一下步骤,因为比较重要,所以还是在这里贴一下吧:

  1. ResouceLoader加载配置信息

  2. BeanDefintionReader解析配置信息,生成一个一个的BeanDefintion

  3. BeanDefintion由BeanDefintionRegistry管理起来

  4. BeanFactoryPostProcessor对配置信息进行加工(也就是处理配置的信息,一般通过PropertyPlaceholderConfigurer来实现)

  5. 实例化Bean

  6. 如果该Bean配置/实现了InstantiationAwareBean,则调用对应的方法

  7. 使用BeanWarpper来完成对象之间的属性配置(依赖)

  8. 如果该Bean配置/实现了Aware接口,则调用对应的方法

  9. 如果该Bean配置了BeanPostProcessor的before方法,则调用

  10. 如果该Bean配置了init-method或者实现InstantiationBean,则调用对应的方法

  11. 如果该Bean配置了BeanPostProcessor的after方法,则调用

  12. 将对象放入到HashMap中

  13. 最后如果配置了destroy或者DisposableBean的方法,则执行销毁操作

640?wx_fmt=png
Application中Bean的声明周期

其中也有关于BPP图片:

640?wx_fmt=jpeg
BBP所在的位置

5.1为什么特意讲BPP?

Spring AOP编程底层通过的是动态代理技术,在调用的时候肯定用的是代理对象。那么Spring是怎么做的呢?

我只需要写一个BPP,在postProcessBeforeInitialization或者postProcessAfterInitialization方法中,对对象进行判断,看他需不需要织入切面逻辑,如果需要,那我就根据这个对象,生成一个代理对象,然后返回这个代理对象,那么最终注入容器的,自然就是代理对象了。

Spring提供了BeanPostProcessor,就是让我们可以对有需要的对象进行“加工处理”啊!

六、认识Spring事务几个重要的接口

Spring事务可以分为两种:

编程式事务在Spring实现相对简单一些,而声明式事务因为封装了大量的东西(一般我们使用简单,里头都非常复杂),所以声明式事务实现要难得多。

在编程式事务中有以下几个重要的了接口:

640?wx_fmt=png
PlatformTransactionManager解析

在声明式事务中,除了TransactionStatus和PlatformTransactionManager接口,还有几个重要的接口:

最后

本文主要讲了Spring事务管理一些比较重要的知识点,当然在学习的过程中还看到其他的知识点,如果想要继续学习的同学不妨通过下面给出的参考资料继续阅读。

参考资料:

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

640?wx_fmt=jpeg
帅的人都关注了
觉得我的文章写得不错,不妨点一下 好看 并 分享 给朋友!


一文读懂医疗大模型测评基准 面对市场上浩若星海的大模型,医院管理者如何采购适合自身场景的解决方案?如何选取好的模型作为基础进行课题研究?都是医院需要特别重视的问题。评测基准则benchmark是这些问题的重要解法,国内北京、上海、浙江已然开展了相关的标准化工作。 阅读详情

相关推荐

【01、Go与VSCode的安装】

小白学Go语言

wangruil的博客 1536

异常

结构图: 1、java.lang.StackOverflowError: public class StackOverErrorTest { public static void main(String[] args) { stackOverErrorTest(); } private static void stackOverErrorTest(...

wojiao228925661的博客 1143

GB28181 2022 配置信令

基本参数视频参数选项视频参数属性配置巡航轨迹

ww506772362的专栏 1630

Sentinel 服务启动报错

Sentinel 服务端启动报错 问题:运行java -jar sentinel-dashboard-1.8.2.jar命令启动sentinel 服务端报错; 2021-08-01 23:37:29 [main] ERROR o.s.boot.SpringApplication - Application run failed java.lang.IllegalStateException: Cannot load configuration class: com.alibaba.csp.sentine

weixin_43955071的博客 5491

当AI学会自我验证:Chain-of-Verification如何杜绝错误决策?

2025年,大模型"幻觉"问题已成为企业落地AI的最大障碍之一——金融风控中1.2%的误判率可能导致千万级损失,医疗诊断中3%的错误可能危及生命,法律文书中5%的事实偏差可能引发合规风险。MetaAI与Google联合提出的**Chain-of-Verification(CoVe,验证链)**技术,让AI具备"自我审视"能力,通过结构化验证流程将幻觉率降低68%+,在复杂决策场景准确率提升至95%+。本文系统拆解CoVe的技术原理、实施路径与行业实战,为企业提供AI决策可靠性保障的完整方案。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1081

AppStore逆向分析:从网络抓包到自动化模拟的完整实践

在移动应用生态中,理解客户端与服务器之间的通信协议是进行自动化测试、数据分析和系统集成的关键技术基础。通过分析网络请求与响应,可以深入理解认证、会话管理和数据交换的原理,这对于构建稳定的自动化流程至关重要。其技术价值在于能够实现合法场景下的流程模拟,例如应用元数据监控、沙盒环境测试或内部工具开发。在实际应用场景中,开发者常需处理登录态维持、请求签名验证及风控策略应对等挑战。本文聚焦于AppStore这一封闭生态,详细拆解了其登录、查询等核心环节的通信机制,并探讨了使用Python结合抓包工具进行安全逆向分析

weixin_42524171的博客 926

项目难点——【1】事务控制@Transactional

项目难点——【1】事务控制@Transactional

weixin_45565886的博客 827

Linux -- 图形界面配置Samba;system-config-samba工具

图形界面配置Samba6.6.1 system-config-sambasystem-config-samba是Red Hat公司专门为Samba服务器管理编写的图形界面的管理工具,通过system-config-samba几乎可以完成对Samba服务器的所有配置,所以在只希望通过Samba服务器实现一些简单的资源共享时,system-config-samba是一个不错的选...

weixin_33695450的博客 2200

Java 异常处理

throw:抛出一个异常,可以是一个自定义异常,语法//抛出自定义异常//抛出运行期异常自定义异常Studentreturn id;} else {// throw new RuntimeException("学员编号不能为负数");//抛出运行期异常//抛出自定义异常throw new RuntimeException(new MyException("学员编号不能为负数"));测试类。

qq_53605652的博客 585

组态王与SqlServer数据库交互总结

组态王可以与SqlServer、mysql、acess、oracle等数据库进行数据交互。 本文重点梳理了如何把组态王中的数据保存到SqlServer数据库中,并使用ADO控件对数据库中的数据进行查询。 一、数据存到SQL数据库 1.新建记录体 2、创建表格模板(用于创建数据库中的表格) 3、打开sqlserver,新建数据库 4、创建ODBC数据源 选择自己新建的数据库 5.使用SQLConnect函数连接数据库,SQLCraetTable函数用于在数据库中创建表格 6.使用

逍遥子的博客 2万+

Sigrity Power Tree如何进行直流压降仿真分析操作指导

Sigrity Power Tree模式可以用于前仿真,在没有layout文件的情况下对电源进行直流压降仿真分析,用于评估原理图设计以及器件选型是否合理。Model:设置为Equal Current,设置为等电源模型,意思该负载每个电源pin都是等电流的。Current:设置每个负载的电流,U30为3A,U3-U6各为1A。Nominal Current:设置能够承载的最大电流,设置为10A。Upper/ Lower Tol:设置为压降范围为5%Output Current:设置输出电流为10A。

weixin_54787054的博客 732

Java异常处理

/抛出自定义异常//抛出运行期异常自定义异常Studentreturn id;} else {// throw new RuntimeException("学员编号不能为负数");//抛出运行期异常//抛出自定义异常throw new RuntimeException(new MyException("学员编号不能为负数"));测试类。

weixin_65081564的博客 431

huggingface下载提示huggingface_hub.errors.EntryNotFoundError:404 Client Error: (Request 1D: Root...如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1232

多线程怎么配置事务_一文带你看懂Spring事务!

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3ySpring事务管理我相信大家都用得很多,但可能仅仅局限于一个@Transactional注解或者在XML中配置事务相关的东西。不管怎么说,日常可能足够我们去用了。但作为程序员,无论是为了面试还是说更好把控自己写的代码,还是应该得多多了解一下Spr...

weixin_39548972的博客 1444

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

一文带你看懂Spring事务! 侵立删

前言 Spring事务管理我相信大家都用得很多,但可能仅仅局限于一个@Transactional注解或者在XML中配置事务相关的东西。不管怎么说,日常可能足够我们去用了。但作为程序员,无论是为了面试还是说更好把控自己写的代码,还是应该得多多了解一下Spring事务的一些细节。 这里我抛出几个问题,看大家能不能瞬间答得上: 如果嵌套调用含有事务的方法,在Spring事务管理中,这属于哪个知...

心神沫沫的收藏 259

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

一文看懂Spring事务传播机制

所谓事务的“传播”指的是多个包含事务的方法互相调用时,事务是如何传播的。本文首先介绍Spring中的七种事务传播方式,然后针对每一种传播方式举例进行讲解,看完就能完全理解Spring的事务传播机制。

a20100997的博客 1426

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

一文带你认识Spring事务

前言 只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y Spring事务管理我相信大家都用得很多,但可能仅仅局限于一个@Transactional注解或者在XML中配置事务相关的东西。不管怎么说,日常可能足够我们去用了。但作为程序员,无论是为了面试还是说更好把控自己写的代码,还是应该得多多了解一下S...

3y 743

一文看懂spring事务原理

1、摘记 事务的作用 事务操作包含两个目的,数据一致以及操作隔离。 数据一致是指事务提交时保证事务内的所有操作都成功完成,并且更改永久生效;事务回滚时,保证能够恢复到事务执行之前的状态。 操作隔离则是指多个同时执行的事务之间应该相互独立,互不影响。 隔离级别 MySQL的InnoDB引擎提供四种隔离级别(即ACID中的I): 读未提交(READ UNCOMMITTED) 读已提交(READ COMMITTED) 可重复读(REPEATABLE READ) 串行化(SERIALIZABLE)

曳凡的博客 981

【Spring进阶系列丨最终篇】一文详解Spring中的事务控制

- 事务需要放在业务层(service) - Spring的事务是基于AOP的 - Spring的事务控制有两种:编程式事务【了解】和==声明式事务==【重点】 - 声明式事务分为:基于xml配置和基于注解配置

陈橘又青的博客 2万+

【Spring事务机制】一文讲解spring事务机制

spring事务是什么?什么是事务的隔离级别?什么是事务的传播机制?

Hanson的博客 1585

一文带你了解Spring中的事务管理

声明式、编程式事务怎么选?spring事务管理底层源码解析、spring中事务是跟线程绑定的,事务只能控制当前线程的操作。

qq_42394044的博客 1336
上一篇: Docker镜像细节
下一篇: 【Java】十道校招常见的面试题
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值