36.从零开始学springboot-事务失效问题详解

聊聊spring事务失效的12种场景,太坑了 前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了。 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据。为了保证操作的原子性(要么同时成功,要么同时失败),避免数据不一致的情况,我们一般都会用到spring事务。 确实,spring事务用起来贼爽,就用一个简单的注解:@Transactional,就能轻松搞定事务。我猜大部分小伙伴也是这样用的,而且一直用一直爽。 但如果你使用不当,它也会坑你于无形。 今天我们就一起聊聊,事务失效的一些场景,说不定你已经中招了。不信,让我们 阅读详情

前言

小编最近使用springboot事务时,发现了点问题

问题

ServiceA

    @Transactional
    public void addStudent() {
        Student student = new Student();
        student.setAge(20);
        student.setName("学生");
        studentMapper.insert(student);
        int i = 1 / 0;
    }

      public void addStudent2() {
        addStudent();
    }

可以看出,我们在addStudent()方法上加了事务注解@Transactional,
所以,方法内抛出任意异常,都会回退,记录不会插入成功!

addStudent2()方法仅仅是内部调用了addStudent()方法,没有其它操作,效果应该和addStudent()一模一样.

我们在Controller直接调用addStudent()方法,会发现抛出了异常,记录没有被成功插入,而是被回退了.

image.png

但是,当我们调用addStudent2()时,发现虽然也抛出异常了,但是记录居然插入成功了!!

为什么会出现这种情况?

原因

SpringBoot 会扫描@Transactional的类和方法,并通过动态代理实现启动事务的代理方法。

在一个Service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调
用,都不会开启新的事务. 是因为Spring采用动态代理机制来实现事务控制,而动态
代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理
了!

一句话描述就是

同一个类中,非事务方法(addStudent2)调用事务方法(addStudent),事务是无法生效的.

解决方案

  1. 将带有@Transactional注解的方法移到另一个类中,发起类之间的方法调用。
    ServiceB
    @Transactional(propagation = Propagation.REQUIRED)
    public void addStudent() {
        Student student = new Student();
        student.setAge(20);
        student.setName("学生");
        studentMapper.insert(student);
        int i = 1 / 0;
    }

ServiceA

    public void addStudent2() {
        ServiceB.addStudent();
    }
  1. 在入口类添加注解方式暴漏代理对象,
@EnableAspectJAutoProxy(exposeProxy = true)

image.png

记得在pom.xml引入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>

image.png

然后在Service中通过代理对象AopContext.currentProxy()去调用方法。

    @Transactional(propagation = Propagation.REQUIRED)
    public void addStudent() {
        Student student = new Student();
        student.setAge(20);
        student.setName("学生");
        studentMapper.insert(student);
        int i = 1 / 0;
    }

    public void addStudent2() {
        ((TransactionService)AopContext.currentProxy()).addStudent();
    }

以上两种方式均能使得事务生效.

说到这里,顺便看了下事务的传播机制

SpringBoot 事务传播机制

@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加入事务, 没有的话新建一个(@Transactional 默认使用这种方式)

@Transactional(propagation=Propagation.NOT_SUPPORTED)
容器不为这个方法开启事务

@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务

@Transactional(propagation=Propagation.MANDATORY)
必须在一个已有的事务中执行,否则抛出异常

@Transactional(propagation=Propagation.NEVER)
必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)

@Transactional(propagation=Propagation.SUPPORTS)
如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

请关注我的订阅号

订阅号.png

宝塔MySQL8.0.36有时无法访问(大约15秒左右),目前CPU占用1,如何解决? 🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。 阅读详情

相关推荐

Python地理空间数据库之geopandas使用详解

地理空间数据分析在许多领域中都有着广泛的应用,包括地理信息系统(GIS)、城市规划、环境科学、地质勘探等。Python GeoPandas是一个强大的库,旨在简化地理空间数据的处理和分析。本文将深入介绍GeoPandas库,包括其基本概念、功能特性、示例代码以及在实际应用中的应用场景。

Rocky006的博客 1万+

Spring事务理解和配置

文章目录1 Spring事务1.1 事务简介1.1.1 什么是事务1.1.2 事物的特性1.1.3 不考虑事物会引发的安全问题1.1.4 事务隔离级别1.2 事务的传播行为1.3 编程式事务(需要手动写代码,了解)1.3.1 配置平台事务管理器1.3.2 Spring提供了事务管理的模板类1.3.3 在业务层注入事务管理的模板1.3.4 编写事务管理的代码1.4 声明式事务(xml配置)1.4.1 配置事务管理器1.4.2 配置增强1.4.3 AOP的配置1.5 声明式事务(注解)1.5.1 配置事务管理器

Student108的博客 2845

Verilog中generate for循环的5个实战技巧(附完整代码示例)

本文详细介绍了Verilog中generate for循环的5个高级实战技巧,包括参数化模块实例化、条件化生成、多维硬件结构实现等,并附有完整代码示例。这些技巧能显著提升FPGA开发效率,特别适合中级Verilog开发者学习应用。

weixin_28725949的博客 187

面试突击:SpringBoot 事务不回滚?怎么解决?

本文我们介绍了 5 种事务不自动回滚的场景和相应的解决方案,开发者应该根据自己的实际情况,选择合适自己解决方案进行处理。

Huangjiazhen711的博客 2250

VSCode搭配Keil开发STM32:从环境配置到代码跳转全流程(避坑指南)

本文详细介绍了如何使用VSCode搭配Keil进行STM32开发,从环境配置到代码跳转的全流程指南。通过安装必备插件和正确配置项目文件,开发者可以在VSCode中享受现代编辑器的便捷功能,同时保留Keil的编译调试能力,提升嵌入式开发效率。

weixin_28832121的博客 253

Unity布娃娃系统 Ragdoll Mecanim Mixer使用

6. 选完之后,左键下面的hip等角色各个部位不松开鼠标,拖拽连接到上面Amature的各个部位,如图,下面所有部位都连接完之后,第二步点击Configure Selected Bones确认你的部位连接选择。要做一个布娃娃和动画混合的项目,这个插件是比较不错的,搜了一圈文章教程也是抄来抄去,抄的没有头没有尾,自己摸索着用了一下,记录使用过程吧。8. 之后就点击步骤7图一中的Create Ragdoll,会发现player结构发生变化,如图。4. 添加完脚本之后会显示你的player结构,如图。

SuShengQuanshiW的博客 1647

Springboot事务不生效的几种情况

Springboot事务

m0_37377048的博客 3193

[官方培训]22-UE资产优化 Epic 肖月 笔记

Nanite+Lumen目标:面向TA,美术,不影响视觉的前提下,优化运行和编辑效率引擎:UE5.1延迟管线平台:主流PC,Windows 10 with DX12。

Tcohneyn的博客 1574

SpringBoot(八) SpringBoot中的事务

事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序 执行逻辑单元(Unit)。事务具有四个特征,分别是原子性(Atomicity )、一致性(Consistency )、隔离性(Isolation) 和持久性(Durability),简称为事务的ACID特性。

这里是阿安的博客 2万+

华三模拟器实战:3分钟搞定路由器DHCP地址池配置(附常见错误排查)

本文提供华三模拟器中路由器DHCP地址池的实战配置指南。通过分步详解,帮助用户在3分钟内完成基础设置,并深入讲解多地址池、中继配置等进阶应用。文章重点剖析了DHCP服务无法工作的常见原因,提供从客户端到服务器的系统性排错方法,助力快速定位并解决地址分配失败、获取参数错误等典型问题。

w1x2y3的博客 360

【头歌】链栈的基本操作及应用

另外,在算法的开始和结束时,栈都应该是空的,所以匹配到最后还要判断栈是否为空,若空,则说明匹配成功,返回1。其中表达式只包含三种括号,花括号{}、中括号[]、圆括号(),即它仅由 (、)、[、]、{、}六个字符组成。预期输出: 栈中元素依次为:12 47 5 8 6 92 45 63 75 38 4 29 弹出的栈顶元素 e=29 栈空否:0(1:空 0:否) 栈顶元素 e=4 栈的长度为11 清空栈后,栈空否:1(1:空 0:否)// 若栈不空,则用e返回S的栈顶元素,并返回OK;

qq_39977056的博客 4383

SpringBoot设置Session失效时间

1 #Session超时时间设置,单位是秒,默认是30分钟 2 server.session.timeout=10 然而并没有什么用,因为SpringBoot在TomcatServletWebServerFactory代码中写了这个 1 private long getSessionTimeoutInMinutes() { 2 Duration...

weixin_30245867的博客 5447

AXI总线详解完结篇

经过几个月的整理和发文,AXI总线详解系列正式迎来最终篇,内容基本涵盖了上一篇文章的全部内容。 所有文章的链接如下: 1、 AXI总线详解 2、AXI总线详解-总线和接口以及协议 3、AXI协议中的通道结构 4、AXI总线详解-AXI4读写操作时序及AXI4猝发地址及选择 5、AXI4交换机制 6、ZYNQ中DMA与AXI4总线-DMA简介 7、AXI总线详解-不同类型的DMA 8、AXI总线详解-DMA内部寄存器的读写方式 9、AXI总线详解-几种应用DMA的场合 10、Altera Scatter-G.

OpenFPGA的博客 5484

Spring事务失效的各种场景总结及源码分析

本文将总结并分析Spring事务失效的各种场景,帮助你全面了解事务失效的原因和解决方案,让你不再被事务问题困扰。上面的事务将不会生效,这是因为主线程与子线程使用的不是同一个Connection对象,Spring事务执行会为每一个执行线程绑定一个Connection对象。以上方法是protected修饰的,事务将失效,默认Spring支持支public修饰的方法。因为无法重写save方法,首先是没法对方法进行增强处理,其次只能调用父类的save方法,而父类中的所有属性(需要注入的)都将是null。

竹林幽深 109

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SpringBoot实现6种JWT令牌失效方案

每种方案都有其优缺点和适用场景,选择合适的方案取决于应用的安全需求、性能要求和架构设计。在实际应用中,常常需要组合使用多种策略,构建多层次的安全防护。

z1ztai的博客 892

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

设计好接口的 36 个锦囊!

点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天 10:33更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT ...

芋艿V 812

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Token失效的6种方案

每种方案都有其优缺点和适用场景,选择合适的方案取决于应用的安全需求、性能要求和架构设计。在实际应用中,常常需要组合使用多种策略,构建多层次的安全防护。

m0_73735578的博客 1678

Springboot拦截器中跨域失效的问题、同一个接口传入参数不同,一个成功,一个有跨域问题、拦截器和@CrossOrigin和@Controller

Springboot拦截器中跨域失效的问题、同一个接口传入参数不同,一个成功,一个有跨域问题、拦截器和@CrossOrigin和@Controller、- 同一个接口,传入不同参数进行值的修改时,一个成功,另一个竟然失败,而且是**跨域问题** - 拦截器内的request参数调用getHeader方法时,获取不到前端设置的请求头,且浏览器显示有,但是后端输出后只有对于的key,而且key变成了`access-control-request-headers`的value - 拦截器失效、跨域问题

不知道你是通过何种途径访问到这里,总之欢迎来到red velet的博客 2828

springboot配置多数据源后mybatis拦截器失效

springboot配置多数据源后mybatis拦截器失效,参考原文https://www.jianshu.com/p/36fb90db79ce 搞了半天不知道为什么分页失效,找到这篇文章 修改代码如下,完成分页状况 ...

qq_42170268的博客 2150

关于最新的springboor中lombok失效,@Data等注解不起作用的解决方法

直接搜索lombok,并且将springboot自己带的lombok进行注释,即可使用自己的lombok。最近创建新项目时,不勾选lombok,进行手动添加。

Nut_ddddou的博客 345

springboot

对 方法注释 用于修饰方法 主要功能是将修饰方法的返回对象 注入spring容器中 其他组件可通过依赖注入的方式使用这个对象。与autowried一起 但要指定 注入的Bean的名称 用于存在多个相同类型的bean时 可以指定使用哪个容器。将一个类标识为spring的组件(Bean)可以被Spring容器自动检测和注册 通用注解适用于任何层次的组件。标识控制层组件 @component的特化 用于表示web控制器 处理http请求 并返回视图或者响应数据。按名称自动注入依赖对象 (默认)

2301_77208597的博客 601

MyBatis-Flex与SpringBoot整合开发实战指南

ORM框架通过对象关系映射简化数据库操作,MyBatis作为主流Java持久层框架,其增强版MyBatis-Flex在动态SQL支持上更具优势。通过注解驱动和链式API,开发者能减少40%以上的样板代码,特别适合快速迭代的中小型项目。与SpringBoot整合后,利用其自动配置特性可快速搭建微服务架构。在数据查询场景中,MyBatis-Flex的@Relation注解简化了多表联查,而动态表名功能则完美支持多租户系统。对于需要处理高并发的场景,建议结合HikariCP连接池和批量操作优化性能。

weixin_30700977的博客 356

Spring @Async 内部调用失效问题:五种解决方案实战分析

解决方案实现复杂度代码侵入性额外依赖架构清晰度适用场景自我注入低低(仅添加一个自注入字段,无方法逻辑修改)无中简单项目,快速解决中中中需要明确控制代理获取AopContext中中需开启 exposeProxy中不想增加依赖字段拆分服务高低无高大型项目,关注点分离手动 TaskExecutor高高(需修改方法注解和调用逻辑)高需要精细控制异步执行需灵活处理返回值需要复杂异步编排。

qq_35485206的博客 1060

Java面试被问到的问题

Java面试问题

qq_43379611的博客 7137
上一篇: 35.从零开始学springboot-数据库版本管理Flyway
下一篇: 资源贴-Python人工智能
码哥说
博客等级 码龄8年 5645粉丝 172原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码哥说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值