Spring事务失效的几种情况,这次清晰了

Flowable 6.6.0 BPMN用户指南-(1)入门 - 1.3.4 旁路:事务性 1.3.4 旁路:事务性 In Flowable, database transactions play a crucial role to guarantee data consistency and solve concurrency problems. When you make a Flowable API call, by default, everything is synchronous and part of the same transaction. Meaning, when the m 阅读详情

简述

在日常开发过程中,我们经常会遇到需要使用事务的场景,尤其是微服务盛行的当下,分布式事务也显得尤为重要,据了解很多使用微服务的项目,并没有处理分布式事务……今天不聊分布式事务,先说说我们在单应用的情况下,会有哪些情况导致事务失效呢?

详解

1. 底层数据库引擎不支持事务

以MySQL为例,它有多种引擎,MyISAM引擎不支持事务操作,InnoDB引擎支持事务,MySQL从5.5.5开始默认的引擎是InnoDB,之前的版本默认的都是MyISAM,所以说如果是非常老的项目,这个需要考虑下。

2. 被@Transactional 注解修饰的方法为非public类型

如果被@Transactional注解修饰的方法,修饰符非public或者被final修饰,则事务会失效,因为AOP没办法为这样的方法生成一个代理,自然事务就无法生效。这个在Spring的官方文档里面也有说明。

在这个地方有个详细讨论过程:https://stackoverflow.com/questions/4396284/does-spring-transactional-attribute-work-on-a-private-method

3. 异常被吃掉了

如果异常被 catch 住,那事务也是会失效呢,伪代码如下:

@Transactional
public void test(){
  try{
    //插入一条数据
    insertA();
    //更改一条数据
    updateB();
  }catch(Exception e){
    log.error("异常被捕获了,事务就失效了",e);
  }
}
4. 异常抛出类型错误

@Transactional 注解有个属性:rollbackFor,这个属性可以设置想要回滚的异常,那它默认的异常是什么?

不要犹豫直接告诉我答案,它默认回滚的是:RuntimeException,如果说我们没有设置这个属性,而且抛出的异常比这个大,那么事务就不会回滚,例如:

@Transactional
public void test(){
  try{
    //插入一条数据
    insertA();
    //更改一条数据
    updateB();
  }catch(Exception e){
    // 这个时候事务就不会回滚
    throw new Exception("操作失败!");
  }
}
5. 本类方法调用

这一个应该是最容易踩坑的了,先来看两段伪代码:

代码一:

@Service
public class TestServiceImpl implements TestService {

    public void testA() {
        // 查询数据,并进行一些判断
        // 调用另外一个方法
        testB();
    }
    
    @Transactional
    public void testB(Test test) {
        // update test
    }
}

问题:testA()方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 testB() 方法,testB() 方法上的事务管用吗?

代码二:

@Service
public class TestServiceImpl implements TestService {

    @Transactional
    public void testA() {
        // 查询数据,并进行一些判断
        // 调用另外一个方法
        testB();
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void testB(Test test) {
        // update test
    }
}

问题:在 testA() 方法上加了 @Transactional,testB() 的注解上加了 REQUIRES_NEW 新开启一个事务,那么新开的事务管用么?

既然这么问了,答案其实大家都知道了,这两段伪代码的事务都是不管用的。

因为他们是本类方法直接调用,这个时候会用this关键字,没有经过 Spring 的代理类去调用此方法,从而没有开启事务管理,默认只有在外部调用事务才会生效。

所以说:加事务注解的方法给本类里面的方法调用,事务不生效!

有多种解决方法:

  • 最直白的就是把方法拆出来,放在两个类里面(Spring推荐的一种方式);
  • 在类里面注入自己,用注入的对象再调用另外一个方法,这个不太优雅;
  • 在Spring的配置里面增加一段配置:<aop:aspectj-autoproxy expose-proxy="true"/>
6. 没有被spring管理

当这个类只是一个普通类,没有被spring管理成为一个Bean对象,那它很自然的就不能使用spring提供的事务管理了,事务自然就不生效。例如:把@Service注解去掉,这个时候事务就不会生效,小伙伴们可以试试。

总结

以上列举了几种常见的事务失效的原因,其实发生最多就是异常被吃掉了、异常抛出类型错误、本类方法调用不对这三个了,这三点只要在日常码代码的时候注意一下,基本就不会有问题了。

当然事务失效可能还有其他原因,欢迎私信我一起学习,一起成长!

另外,既然说到了Spring的事务,那就不可不提Spring的事务传播机制,总共有7种,一起复习一下,如下:

  • PROPAGATION_REQUIRED:Spring的默认传播级别,如果上下文中存在事务则加入当前事务,如果不存在事务则新建事务执行。

  • PROPAGATION_SUPPORTS:如果上下文中存在事务则加入当前事务,如果没有事务则以非事务方式执行。

  • PROPAGATION_MANDATORY:该传播级别要求上下文中必须存在事务,否则抛出异常。

  • PROPAGATION_REQUIRES_NEW:该传播级别每次执行都会创建新事务,并同时将上下文中的事务挂起,执行完当前线程后再恢复上下文中事务。(子事务的执行结果不影响父事务的执行和回滚)

  • PROPAGATION_NOT_SUPPORTED:当上下文中有事务则挂起当前事务,执行完当前逻辑后再恢复上下文事务。(降低事务大小,将非核心的执行逻辑包裹执行。)

  • PROPAGATION_NEVER:该传播级别要求上下文中不能存在事务,否则抛出异常。

  • PROPAGATION_NESTED:嵌套事务,如果上下文中存在事务则嵌套执行,如果不存在则新建事务。(save point概念)

有任何问题欢迎微信搜索【Hugh的白板】私信我,一起探讨,一起学习

JuiceFS:写流程源码解析+刷盘+数据一致性分析 juicefs是一款面向云原生设计的高性能分布式文件系统,本文分析写流程,及其如何保证数据一致性。 阅读详情

相关推荐

8个Spring事务失效的场景,你碰到过几种?

作为Java开发工程师,相信大家对Spring种事务的使用并不陌生。但是你可能只是停留在基础的使用层面上,在遇到一些比较特殊的场景,事务可能没有生效,直接在生产上暴露了,这可能就会导致比较严重的生产事故。今天,我们就简单来说下Spring事务的原理,然后总结一下spring事务失败的场景,并提出对应的解决方案。本文简单阐述了下Spring中事务实现的原理,同时列举了8种Spring事务失败的场景,相信很多朋友可能都遇到过, 失败的原因也有详细说明。希望大家对Spring事务有一个新的认识。

m0_71777195的博客 3471

Flowable流程高级课程

本课程是《Flowable流程入门课程》的后续高级课程。在学习本课程前,应先学习入门课程,以掌握相关基础知识。高级课程着重讲解Flowable工作流的高级概念、复杂理论和实战应用。课程内容包括流程管理思想、技术与标准、工作流的控制模式和资源模式;Flowable数据库表及变量;与Spring、Spring Boot的集成;BPMN 2.0主要类图;Flowable高级服务如JAVA服务任务、脚本任务、Web Service任务、外部工作者任务、多实例任务、补偿处理程序、子流程和调用活动等;Flowable事件侦听器、执行侦听器和任务侦听器;Flowable历史和REST API;Flowable事务、并发性、身份管理及LDAP集成;Flowable高级主题如流程实例迁移、异步执行器的设计与配置、用于高并发的UUID ID生成器、多租户、高级流程引擎配置、执行自定义SQL和实验性流程调试器等;Flowable Eclipse设计器特性及定制;Flowable 事件注册;Flowable相关标准和规范如ISO8601标准和cron等。本课程对Flowable官方文档进行了彻底梳理和融汇贯通,并结合实践,形象生动、系统全面、简单易懂地呈现给大家,让大家从开源软件文档冗长耗时、英文晦涩难懂、概念理解困难、知识点分散等困境中解脱出来,从而能快速地将Flowable具有的高级特性应用到项目的高级需求和复杂实践中去。课程特色:案例和代码驱动、基础概念与经典实战相结合、知识环节融会贯通、关联知识平滑拓展、概念和原理展示形象生动。

盘点导致Spring事务失效的4个场景

事务是我们日常开发工作中无法避免的一个功能,深刻理解事务的运行机制,正确使用事务的声明式操作,才能让我们写出更健壮的代码。

m0_71777195的博客 605

SpringBoot事务管理

文章目录1.Spring中的事务2.事务的传播行为(propagation behavior)3.事务的隔离级别(isolation level)4.SpringBoot中使用事务管理 1.Spring中的事务 Spring并不直接管理事务,而是通过各种事务管理器来调用特定平台的事务实现,用户在使用事务时不需要关心底层的实现。针对各个持久化场景,Spring提供了各个事务管理器,他们都继承了AbstractPlatformTransactionManager,实现了ResourceTransactionMa

qq_41120971的博客 692

手把手教你用闲置安卓手机搭建个人收款系统(蓝鲸支付私有化部署实战)

本文详细介绍了如何利用闲置安卓手机搭建个人收款系统,实现私有化支付部署。通过开源技术栈和容器化方案,零成本构建安全、高效的支付网关,解决传统支付平台的数据安全和资金风险问题。特别适合个人开发者和小微企业主,无需复杂审批,资金实时到账,显著降低运营成本。

weixin_30363285的博客 380

Dr_can Kalman Filter学习笔记(一)

本文是在b站Dr_can的卡尔曼滤波课程学习过程中的学习笔记

苏大侠的博客 1051

Spring事务this自调用的理解误区?真的会让事务失效吗?

我们经常谈到Spring事务失效会有多种场景导致:可参考我另外一篇文章一文清晰讲解@Transactional 注解失效场景@Transactional 应用在非 public 修饰的方法上@Transactional 注解属性 propagation 设置错误@Transactional 注解属性 rollbackFor 设置错误同一个类中方法调用,导致@Transactional失效异常被你的 catch“吃了”导致@Transactional失效数据库引擎不支持事务。

Apple_Boy的博客 6634

Autoware1.14-摄像头目标检测YOLO-V3

在Autoware1.14中部署YOLOV3

weixin_43687753的博客 3139

Spring事务几种失效原因

在使用@Transactional注解声明事务时,有时我们想自定义回滚的异常,spring也是支持的。可以通过设置参数,来完成这个功能。@Slf4j@Service如果在执行上面这段代码,保存和更新数据时,程序报错了,抛了SqlException、DuplicateKeyException等异常。而BusinessException是我们自定义的异常,报错的异常不属于BusinessException,所以事务也不会回滚。

Go_ahead_forever的博客 576

数据集FFHQ和LSUN介绍【包含FFHQ1024,515,256,128分辨率图像获取方法】

FFHQ全称Flickr-Faces-High-Quality(Flickr-Faces-HQ),最初是作为生成式对抗网络(GAN)的基准创建的,也用于StyleGAN的训练数据集中,并由英伟达于2019年开源。CVPR_2019Flickr-Faces-HQ (FFHQ)其由 70,000 张分辨率为 1024×1024 的高质量 PNG 图像组成,在年龄、种族和图像背景方面包含相当大的差异。它对眼镜、太阳镜、帽子等配饰也有很好的覆盖。

zik的博客 3977

Android 14.0 SystemUI下拉通知栏通知去掉长按事件

在14.0的系统rom产品定制化开发中,在systemui模块中关于下拉状态栏这块也是非常重要的部分,最近在关于systemui下拉通知栏的每条通知部分 要求去掉通知栏通知的长按事件,不需要长按功能,所以就需要分析下关于长按事件是在哪里注册的,然后去掉就可以了,接下来分析实现 相关功能

安卓兼职framework和app工程师的博客 276

别再踩坑!Spring事务@Transactional失效?一文读懂参数与8大失效场景

在我们开发Spring Boot应用中,很多小伙伴以为只要在方法上加一个 @Transactional,事务就能自动回滚,保证数据一致性。但实际开发中,事务经常出现失效的情况:明明抛了异常,数据库还是提交了。你肯定会疑惑:“为什么我加了注解,数据还是没回滚?” 通过本文博主将彻底和小伙伴们说清楚,让大家别再踩坑!从 @Transactional 的参数详解入手,再结合常见事务失效场景给出 正确写法 vs 错误写法 对比,帮助小伙伴们彻底理解 Spring 事务机制。

Micro麦可乐的博客 4746

ABAP 后台作业里的消息机制:把 MESSAGE 写对,避免作业莫名取消

SAP后台作业消息处理机制解析 本文深入剖析了SAP系统中后台作业的消息处理机制,揭示了前台与后台执行环境的关键差异。核心发现包括: 后台作业对消息的处理规则: 所有消息写入Job log而不显示 根据消息类型决定是否继续执行 W警告在列表处理阶段会被自动转为E错误 关键异常处理: 通过error_message可捕获E/A类型消息 A类型消息会触发隐式数据库回滚 未被捕获的E/A消息将导致作业中断 实用解决方案: 将业务提示改为S或I类型 使用DISPLAY LIKE保持前台体验 通过error_mess

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2216

清晰、明了的@Transcation事务嵌套使用

@Transactional注解是Spring框架提供的用于声明事务的注解,作用于类和方法上。在一般或嵌套使用的情况下,有你不知道的潜规则。

devops 9616

基于STM32、HAL库的ZMOD4510AI4R气体传感器驱动程序设计

ZMOD4510AI4R是Renesas公司推出的一款数字空气质量传感器,主要用于检测臭氧(O₃)和总挥发性有机化合物(TVOC)浓度。(status & 0x80)) // 检查数据就绪位。// 等待测量完成 (实际应用中应该使用非阻塞方式)// 转换为ppb (简化转换,实际应根据传感器文档校准)* @param hzmod: ZMOD4510句柄。* @param tvoc: TVOC浓度(ppb)* @param ozone: 臭氧浓度(ppb)* @param hi2c: I2C句柄。

corlin6688的博客 311

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Spring事务传播机制与事务失效问题解决方案

Spring事务通过注解实现,传播机制(Propagation)定义了方法调用时事务的行为。传播机制由枚举定义,位于包。Spring事务传播机制通过REQUIRED等行为管理事务。订单支付系统通过优化传播、解决失效问题,实现P99延迟40ms、QPS 12万。传播REQUIRED通用,独立。失效:分离服务,指定rollbackOn。优化:虚拟线程、连接池。监控Spring事务是高并发系统的基石,未来将在分布式和AI驱动下演进。字数:约5100字(含代码)。如需调整,请告知!传播机制由。

lssffy的博客 1413

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Spring AOP(定义、使用场景、用法、3种事务、事务失效场景及解决办法、面试题)

3.2.1 添加依赖前置通知 @Before:通知方法会在目标方法调用之前执行后置通知 @After:通知方法会在目标方法返回或者抛出异常后调用返回之后通知 @AfterReturning:通知方法会在目标方法返回后调用抛异常后通知:@AfterThrowing:通知方法会在目标方法爬出异常之后调用环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为实现通知方法也就是在什么时机执行什么方法@Aspect // 当前类是一个切面。3种事务、事务失效场景及解决办法

m0_64422133的博客 2797

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

spring 事务传播行为以及失效原因

今天在查看以前写的代码时,看到了事务的使用,感觉自己对这一块并不是特别清晰,所以就系统的学习了一下。在学习过程中发现很多地方自己以前理解的还是有点不对,所以记录一下学习笔记,希望帮助到大家。备注:因为除了PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED,其他的都不是特别难以理解,所以我这里就只对这两个做了一下代码实例。当事务方法被另外一个事务方法调用时,必须指定事务应该如何传播,例如,方法可能继续在当前事务中执行,也可以开启一个新的事务,在自己的事务中执行。 声明式事务

qq_35771266的博客 1811

Spring事务的嵌套

事务嵌套

zuokaopuqingnian的博客 1468

Spring 事务失效排查:先确认代理边界,再看传播行为

Spring 事务失效排查应先确认代理边界,再看异常类型、传播行为、多数据源和线程上下文。事务不是一个注解就能解决的魔法,它是一套调用链规则。把边界画清楚,数据一致性问题才有稳定的排查路径。

alex_goden的博客 5938

Spring事务失效全场景深度解析:从原理到实战避坑指南

在分布式系统与高并发场景下,Spring事务管理是保障数据一致性的核心技术。然而,一个简单的@Transactional注解背后隐藏着诸多"深坑"。本文结合20+生产案例与Spring源码,深度剖析16个事务失效场景,助你构建完整的事务防控体系。

Hello World!你好世界! 1046

Spring事务失效场景?

场景描述:在Spring的事务管理中,如果在一个支持当前事务的方法(比如,已经被标记为@Transactional的方法)中调用了一个需要新事务的方法,如果后者方法抛出了异常,但异常并未被Spring识别为需要回滚事务的异常,那么后者的事务将不会回滚。场景描述:默认情况下,Spring只有在方法抛出运行时异常或者错误时才会回滚事务。解决方案:尽量将事务方法放在不同的类中,或者使用Spring的AopContext.currentProxy()来获取当前类的代理对象,然后通过代理对象调用事务方法。

埃泽漫笔 524

Java面试高频知识点:Spring事务失效的几种场景

这个问题听起来简单,但能回答到位的人,寥寥无几。Spring事务管理是Java开发的基石技能,而事务失效问题,堪称面试现场最常用的“照妖镜”。如果Spring使用的是JDK动态代理,代理的是接口,那么接口上的注解会被读取。但如果代理方式变成了CGLIB(比如类没有实现接口,或者配置强制使用CGLIB),此时代理的是类,接口上的注解就被无视了。配置错误时,比如把内层方法配成SUPPORTS,如果外层有事务就加入,没有就算了。写代码时心血来潮,在方法里捕获了异常,打印日志后吞掉,然后返回了一个正常结果。

searchboy2025的博客 18

Spring 事务

在初始化 Bean 的时候,会进行Bean的后置处理,后置处理时会遍历所有的切面,并查找与当前Bean相匹配的切面,在这里我们要获取事务的属性,有了属性之后才知道是否与切面匹配,这个属性也就是也就是。既然运行到第二个事务的 begin 的时候,A事务(外层的事务) 会自动提交,那就把 begin 和 commit 去掉,将 B 融入 A 事务中,这样就会使 A 事务失效。如果方法 B 有事务注解标识,但是同一个类中的方法 A 没有,A中的方法调用方法 B,此时外部调用方法A,方法B的事务会失效。

m0_73173239的博客 1009

从源码剖析Spring事务失效问题

1.Bean是否是代理对象 2.入口函数是否是public的 3.数据库是否支持事务(Mysql的Mvlsam不支持事务),行锁才支持事务 4.切点是否配置正确 5.内部方法间调用导致事务失效 因为this不是代理对象,可以配置 expose-proxy="true",就可以通过AopContext.currentProxy0)获取到当前类的代理对象。 <! -- expose-proxy="true”类内部可以获取到当前类的代理对象--><aop: aspectj-aut.

Jak的博客 468
上一篇: 你有没有被这跟“针”扎的头皮冒汗?
下一篇: 实用技巧 | Chrome浏览器如何对标签页进行分组整理?
Hugh Pro
博客等级 码龄16年 6粉丝 22原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值