SpringBoot 事务不回滚?怎么解决?
在 Spring Boot 中,造成事务不自动回滚的场景有很多,比如以下这些:
- 非 public 修饰的方法中的事务不自动回滚;
- 当 @Transactional 遇上 try/catch 事务不自动回滚;
- 调用类内部的 @Transactional 方法事务不自动回滚;
- 抛出检查异常时事务不自动回滚;
- 数据库不支持事务,事务也不会自动回滚。
1、非 public 方法解决方案
非public方法中事务不回滚的直接原因是,在非 public 方法上添加的 @Transactional 关键字是无效的,也就是此方法本身是以非事务的方式运行,所以不会自动回滚事务!
因为 @Transactional 使用的是 Spring AOP 实现的,而 Spring AOP 是通过动态代理实现的,而 @Transactional 在生成代理时会判断,如果方法为非 public 修饰的方法,则不生成代理对象,这样也就没办法自动回滚事务了。
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {// Don't allow no-public methods as required.// 非 public 方法,设置为 nullif (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;}// 后面代码省略....}
此问题的解决方案是将方法的权限修饰符改为 public 即可。
2、try/catch 解决方案
当程序中出现了 try/catch 代码时,事务不会自动回滚,这是因为 @Transactional 注解在其实现时,需要感知到异常才会自动回滚,而用户自行在代码中加入了 try/catch 之后@Transactional 就无法感知到异常了,那么也就不能自动回滚事务了。
此问题的解决方案有两种:一种是在 catch 中将异常重新抛出去,另一种是使用代码手动将事务回滚。
1)将异常重新抛出
@Transactional(rollbackFor = Exception.class)public int save() throws Exception {try{int num = 2/0;}catch (Exception e){throw new Exception("算数异常");}return -1;}
2)使用代码手动回滚事务
@Transactional(rollbackFor = Exception.class)public int save() throws Exception {try{int num = 2/0;}catch (Exception e){//将异常抛出//throw new Exception("算数异常");//手动设置事务回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return -1;}
3、调用内部 @Transactional 方法解决方案
调用类内部 @Transactional 的方法不自动回滚事务的原因是,@Transactional 是基于 Spring AOP 实现的,而 Spring AOP 又是基于动态代理实现的,而当调用类内部的方法时,不是通过代理对象完成的,而是通过 this 对象实现的,这样就绕过了代理对象,从而事务就失效了。
解决方案是给调用的方法上也加上 @Transactional
@Transactional(rollbackFor = Exception.class)public int saveing() throws Exception {return save();}//被调用的方法@Transactionalpublic int save(){int num = 2/0;return num;}
4、检查异常的事务解决方案
所谓的检查异常(Checked Excetion)指的是编译器要求开发者必须处理的异常,如下图所示:
检查异常不回滚事务的原因是因为,@Transactional 默认只回滚运行时异常 RuntimeException 和 Error,而对于检查异常默认是不回滚的。
此问题的解决方案是给 @Transactional 注解上,添加 rollbackFor 参数并设置 Exception.class 值
5、数据库不支持事务的解决方案
当我们在程序中添加了 @Transactional,相当于给调用的数据库发送了:开始事务、提交事务、回滚事务的指令,但是如果数据库本身不支持事务,比如 MySQL 中设置了使用 MyISAM 引擎,因为它本身是不支持事务的,这种情况下,即使在程序中添加了 @Transactional 注解,那么依然不会有事务的行为,也就不会执行事务的自动回滚了。
在这种情况下,我们只需要设置 MySQL 的引擎为 InnoDB 就可以解决问题了,因为 InnoDB 是支持事务的,当然 MySQL 5.1 之后的默认引擎就是 InnoDB,引擎的设置分为以下两种情况:
1)在新建表时设置数据库引擎:
CREATE TABLE T1 (i int) ENGINE = INNDB;
2)在修改表时设置数据库引擎:
alter table t1 rngine = MyIsam;
PS:也就是数据库的引擎是和表直接相关的,我们只需要正确的设置引擎之后,事务就可以正常的执行了。
SpringBoot 事务不回滚?怎么解决?相关推荐
- springboot 事务手动回滚_Spring Boot中的事务是如何实现的
1. 概述 一直在用SpringBoot中的@Transactional来做事务管理,但是很少想过SpringBoot是如何实现事务管理的,今天从源码入手,看看@Transactional是如何实现事 ...
- springboot 事务手动回滚_来,讲讲Spring事务有哪些坑?
来自公众号:孤独烟 引言 今天,我们接上文<面试官:谈谈你对mysql事务的认识>的内容,来讲spring中和事务有关的考题! 因为事务这块,面试的出现几率很高.而大家工作中CRUD的比较 ...
- SpringBoot 异常回滚 事务的使用___Springboot @Transactional 事务不回滚
Springboot中事务的使用: 1.启动类加上@EnableTransactionManagement注解,开启事务支持(其实默认是开启的). 2.在使用事务的public(只有public支持事 ...
- java 自定义异常 未回滚_抛出自定义异常,spring AOP事务不回滚的解决方案
spring AOP 默认对RuntimeException()异常或是其子类进行事务回滚,也就是说 事务回滚:throw new RuntimeException("xxxxxxxxxxx ...
- spring boot 项目 事务 不能回滚 代理(not eligible for auto-proxying)
spring 事务机制网上的案例很多,关于事务 不能回滚也有很多的类型,不同的问题有不同的处理方案,本篇博客主要介绍两种事务不能回滚的问题解决方案: 问题一: 在同一个对象中有两个方法,分别未方法A, ...
- sqlsever回滚操作_sqlserver事务与回滚
如果要在Production执行数据改动必须小心,可以使用事务提前验证一下自己写的SQL是不是你期望的.尤其是Update的where 条件有问题的话,跟新的记录就会超出预期的范围.如下面的语句,一着 ...
- [事务] 事务的回滚机制
SpringBoot提供了非常方便的事务操作,通过注解就可以实现事务的回滚,下面我们就说一下如何进行事务操作 1. 事务说明 在Spring中,事务有两种实现方式,分别是编程式事务管理和声明式事务管理 ...
- spring@Transactional注解事务不回滚不起作用无效的问题处理
这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚.后来终于找到了原因. 如果你也出现了这种情况,可以从下面开始排查. 一.特性 先来了解一下@Transactio ...
- 每日一博 - 常见的Spring事务失效事务不回滚案例集锦
文章目录 事务不生效 方法内部调用 修复方法一 : [新加一个Service方法] 修复方法二:[在该Service类中注入自己] 修复方法三:[通过AopContent类]<---- 推荐 访 ...
最新文章
- SAP变式配置的完整指南(中英文双语版)
- Cenos7 部署asp.net core站点
- 数据中心智慧机房解决方案
- Autofac框架初识与应用
- 犹豫了几个月,我还是跳槽了....
- Mediator模式(C++中介者模式含个人Demo源码)
- oracle 密码管理,【转载】Oracle密码管理五大要点(一)
- 西门子g120c面板参数设定_西门子PCS7模拟量单位设置
- linux每天进步一点点-7月15日
- 爬虫:Python爬虫学习笔记之Urllib库
- 从阿尔法狗元(AlphaGo Zero)的诞生看终极算法的可能性
- 天线罩结构的基础知识
- 按键精灵引流脚本实操
- 计算机按姓氏笔画顺序排序规则,【姓氏文化】按姓氏笔画排序的原则
- 哈工大车万翔教授:ACL 2010-2020研究趋势总结
- PhotoShop导入webp格式图片
- 51单片机延时程序(以延时30ms为例)
- Oracle数据库同义词详解
- 【消息】“莓果儿”QQ群
- web前端开发技术实验与实践(第三版)储久良编著 项目12 设计简易网站导航