在 Spring Boot 中,造成事务不自动回滚的场景有很多,比如以下这些:

  1. 非 public 修饰的方法中的事务不自动回滚;
  2. 当 @Transactional 遇上 try/catch 事务不自动回滚;
  3. 调用类内部的 @Transactional 方法事务不自动回滚;
  4. 抛出检查异常时事务不自动回滚;
  5. 数据库不支持事务,事务也不会自动回滚。

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 事务不回滚?怎么解决?相关推荐

  1. springboot 事务手动回滚_Spring Boot中的事务是如何实现的

    1. 概述 一直在用SpringBoot中的@Transactional来做事务管理,但是很少想过SpringBoot是如何实现事务管理的,今天从源码入手,看看@Transactional是如何实现事 ...

  2. springboot 事务手动回滚_来,讲讲Spring事务有哪些坑?

    来自公众号:孤独烟 引言 今天,我们接上文<面试官:谈谈你对mysql事务的认识>的内容,来讲spring中和事务有关的考题! 因为事务这块,面试的出现几率很高.而大家工作中CRUD的比较 ...

  3. SpringBoot 异常回滚 事务的使用___Springboot @Transactional 事务不回滚

    Springboot中事务的使用: 1.启动类加上@EnableTransactionManagement注解,开启事务支持(其实默认是开启的). 2.在使用事务的public(只有public支持事 ...

  4. java 自定义异常 未回滚_抛出自定义异常,spring AOP事务不回滚的解决方案

    spring AOP 默认对RuntimeException()异常或是其子类进行事务回滚,也就是说 事务回滚:throw new RuntimeException("xxxxxxxxxxx ...

  5. spring boot 项目 事务 不能回滚 代理(not eligible for auto-proxying)

    spring 事务机制网上的案例很多,关于事务 不能回滚也有很多的类型,不同的问题有不同的处理方案,本篇博客主要介绍两种事务不能回滚的问题解决方案: 问题一: 在同一个对象中有两个方法,分别未方法A, ...

  6. sqlsever回滚操作_sqlserver事务与回滚

    如果要在Production执行数据改动必须小心,可以使用事务提前验证一下自己写的SQL是不是你期望的.尤其是Update的where 条件有问题的话,跟新的记录就会超出预期的范围.如下面的语句,一着 ...

  7. [事务] 事务的回滚机制

    SpringBoot提供了非常方便的事务操作,通过注解就可以实现事务的回滚,下面我们就说一下如何进行事务操作 1. 事务说明 在Spring中,事务有两种实现方式,分别是编程式事务管理和声明式事务管理 ...

  8. spring@Transactional注解事务不回滚不起作用无效的问题处理

    这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚.后来终于找到了原因. 如果你也出现了这种情况,可以从下面开始排查. 一.特性 先来了解一下@Transactio ...

  9. 每日一博 - 常见的Spring事务失效事务不回滚案例集锦

    文章目录 事务不生效 方法内部调用 修复方法一 : [新加一个Service方法] 修复方法二:[在该Service类中注入自己] 修复方法三:[通过AopContent类]<---- 推荐 访 ...

最新文章

  1. SAP变式配置的完整指南(中英文双语版)
  2. Cenos7 部署asp.net core站点
  3. 数据中心智慧机房解决方案
  4. Autofac框架初识与应用
  5. 犹豫了几个月,我还是跳槽了....
  6. Mediator模式(C++中介者模式含个人Demo源码)
  7. oracle 密码管理,【转载】Oracle密码管理五大要点(一)
  8. 西门子g120c面板参数设定_西门子PCS7模拟量单位设置
  9. linux每天进步一点点-7月15日
  10. 爬虫:Python爬虫学习笔记之Urllib库
  11. 从阿尔法狗元(AlphaGo Zero)的诞生看终极算法的可能性
  12. 天线罩结构的基础知识
  13. 按键精灵引流脚本实操
  14. 计算机按姓氏笔画顺序排序规则,【姓氏文化】按姓氏笔画排序的原则
  15. 哈工大车万翔教授:ACL 2010-2020研究趋势总结
  16. PhotoShop导入webp格式图片
  17. 51单片机延时程序(以延时30ms为例)
  18. Oracle数据库同义词详解
  19. 【消息】“莓果儿”QQ群
  20. web前端开发技术实验与实践(第三版)储久良编著 项目12 设计简易网站导航

热门文章

  1. 2021中级维修电工证考试题库(电工作业)2021职业技能鉴定
  2. 见证奇迹的时刻:让你的头像说话
  3. 原生JDBC连接步骤
  4. python根据url下载图片的方法
  5. Python简单的枫叶形状的词云图
  6. android device id 获取主要用于google 服务
  7. 2008服务器怎么组件共享组,Windows Server 2008服务器文件共享服务器搭建
  8. Django-合并migrations
  9. BCM设计与开发的简单介绍
  10. http请求报400报错