返回顶部
首页 > 资讯 > 后端开发 > Python >SpringBoot事务不回滚的解决方案
  • 648
分享到

SpringBoot事务不回滚的解决方案

2024-04-02 19:04:59 648人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1.非 public 方法解决方案2.try/catch 解决方案解决方案1:将异常重新抛出解决方案2:使用代码手动回滚事务3.调用内部 @Transactional 方法解决方

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 方法,设置为 null
   if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
      return null;
   }
   // 后面代码省略....
 }

此问题的解决方案是将方法的权限修饰符改为 public 即可。

2.try/catch 解决方案

当程序中出现了 try/catch 代码时,事务不会自动回滚,这是因为 @Transactional 注解在其实现时,需要感知到异常才会自动回滚,而用户自行在代码中加入了 try/catch 之后,@Transactional 就无法感知到异常了,那么也就不能自动回滚事务了。

此问题的解决方案有两种:一种是在 catch 中将异常重新抛出去,另一种是使用代码手动将事务回滚。

解决方案1:将异常重新抛出

解决方案2:使用代码手动回滚事务

除了解决方案 1 这种不是很友好的回滚事务的方式之外,我们还可以选择更加友好的,不报错,但可以回滚事务的方式,其核心实现代码如下:

3.调用内部 @Transactional 方法解决方案

调用类内部 @Transactional 的方法不自动回滚事务的原因是,@Transactional 是基于 spring aop 实现的,而 Spring AOP 又是基于动态代理实现的,而当调用类内部的方法时,不是通过代理对象完成的,而是通过 this 对象实现的,这样就绕过了代理对象,从而事务就失效了。

此时我们的解决方案是给调用的方法上也加上 @Transactional,具体实现代码如下:

4.检查异常的事务解决方案

所谓的检查异常(Checked Excetion)指的是编译器要求开发者必须处理的异常,如下图所示:

检查异常不回滚事务的原因是因为,@Transactional 默认只回滚运行时异常 RuntimeException 和 Error,而对于检查异常默认是不回滚的。

此问题的解决方案是给 @Transactional 注解上,添加 rollbackFor 参数并设置 Exception.class 值即可,具体实现代码如下:

5.数据库不支持事务的解决方案

当我们在程序中添加了 @Transactional,相当于给调用的数据库发送了:开始事务、提交事务、回滚事务的指令,但是如果数据库本身不支持事务,比如 MySQL 中设置了使用 MyISAM 引擎,因为它本身是不支持事务的,这种情况下,即使在程序中添加了 @Transactional 注解,那么依然不会有事务的行为,也就不会执行事务的自动回滚了。

在这种情况下,我们只需要设置 MySQL 的引擎为 InnoDB 就可以解决问题了,因为 InnoDB 是支持事务的,当然 Mysql 5.1 之后的默认引擎就是 InnoDB,引擎的设置分为以下两种情况:

在新建表时设置数据库引擎:

在修改表时设置数据库引擎

PS:也就是数据库的引擎是和表直接相关的,我们只需要正确的设置引擎之后,事务就可以正常的执行了。

总结

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

到此这篇关于SpringBoot事务不回滚的解决方案的文章就介绍到这了,更多相关SpringBoot事务不回滚内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: SpringBoot事务不回滚的解决方案

本文链接: https://lsjlt.com/news/168385.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringBoot事务不回滚的解决方案
    目录1.非 public 方法解决方案2.try/catch 解决方案解决方案1:将异常重新抛出解决方案2:使用代码手动回滚事务3.调用内部 @Transactional 方法解决方...
    99+
    2024-04-02
  • 决@Transactional注解事务不回滚如何解决
    决@Transactional注解事务不回滚如何解决?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、特性先来了解一下@Transactional注解事务的特性...
    99+
    2023-06-06
  • php事务回滚不了如何解决
    这篇文章主要介绍了php事务回滚不了如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇php事务回滚不了如何解决文章都会有所收获,下面我们一起来看看吧。php事务回滚不了的解决办法:1、打开相应的PHP文件...
    99+
    2023-07-04
  • spring声明式事务 @Transactional 不回滚的多种情况以及解决方案
    目录一、 spring 事务原理问题一、@Transactional 应该加到什么地方,如果加到Controller会回滚吗?问题二、 @Transactional 注解中用不用加r...
    99+
    2024-04-02
  • redis不支持事务回滚如何解决
    Redis本身是单线程的,并且它使用了类似于命令队列的机制来处理客户端请求。这导致了Redis的事务是部分支持事务回滚的。在Redi...
    99+
    2023-09-16
    redis
  • spring在service层的方法报错事务不会回滚的解决
    目录spring在service层方法报错事务不会回滚解决方法service手动回滚问题spring在service层方法报错事务不会回滚 @Transactional(rollba...
    99+
    2024-04-02
  • spring在service层的方法报错事务不会回滚怎么解决
    这篇文章主要介绍“spring在service层的方法报错事务不会回滚怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“spring在service层的方法报错事务不会回滚怎么解决”文章能帮助大...
    99+
    2023-06-29
  • 完美解决Spring声明式事务不回滚的问题
    疑问,确实像往常一样在service上添加了注解 @Transactional,为什么查询数据库时还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚。于是就对相关代码进行了一番测试,结果发现一下踩进了两个坑,确实...
    99+
    2023-05-31
    spring 声明式事务 不回滚
  • springboot使用mybatis开启事务回滚
    目录1.前言  2.操作(1)提前配置好spring boot + mybatis(2)导入依赖包(3)启动类开启事务管理3.测试(1)父级方法不开启事务,子级开启,让子级方法触发异...
    99+
    2023-02-05
    springboot mybatis 事务回滚 mybatis 事务回滚
  • mongodb事务回滚失败怎么解决
    当 MongoDB 的事务回滚失败时,可能有以下几种解决方法: 检查 MongoDB 版本:首先确保你使用的是 MongoDB ...
    99+
    2023-10-26
    mongodb
  • Spring事务回滚异常怎么解决
    当Spring事务回滚异常时,可以尝试以下解决方法: 检查代码逻辑:首先检查代码逻辑是否正确,是否在事务范围内执行了可能导致异常...
    99+
    2024-03-01
    Spring
  • 关于SpringBoot的异常回滚和事务的使用详解
    目录Springboot中事务的使用:开启事务的方法中事务回滚的情况:Springboot @Transactional 事务不回滚一、异常捕获的原因二、数据库引擎不支持回滚(使用M...
    99+
    2023-05-19
    SpringBoot异常回滚 SpringBoot事务
  • 实现mybatis事务回滚的方法
    今天就跟大家聊聊有关实现mybatis事务回滚的方法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。解决方法:将DataSource配置改为AutoCommit(false)将conn...
    99+
    2023-06-06
  • php事务回滚不了怎么办
    本教程操作环境:windows7系统、PHP8.1版、Dell G3电脑。php事务回滚不了怎么办?问题描述:关于php 事务未执行回滚mysqliphptransactions Transactions not doing the rol...
    99+
    2024-04-02
  • Java多线程事务回滚@Transactional失效处理方案
    目录背景介绍公用的类和方法示例事务不成功操作使用sqlSession控制手动提交事务 背景介绍 1,最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插...
    99+
    2022-11-13
    Java多线程事务回滚 Java @Transactional失效
  • SpringBoot扫描不到Controller的解决方案
    SpringBoot小白创建项目,扫描不到Controller一系列问题 1. 2. 3. 4. 5. 6.还有一种办法是在启动服务类的入门,添加@ComponentSca...
    99+
    2024-04-02
  • 详解Spring事务回滚和事务提交
    目录事务回滚事务提交事务回滚 回滚逻辑如下: 判断是否存在事务,只有存在事务才执行回滚 根据异常类型判断是否回滚。如果异常类型不符合,仍然会提交事务 回滚处理 ...
    99+
    2024-04-02
  • SQL事务回滚的方法是什么
    在SQL中,可以使用ROLLBACK语句来回滚事务。当一个事务出现问题或者需要撤销之前的操作时,可以使用ROLLBACK语句将事务回...
    99+
    2024-04-09
    SQL
  • Spring事务捕获异常后依旧回滚的解决
    目录前沿问题阐述知识点前置条件问题追踪总结前沿 一段生产事故发人深省,在Spring的声明式事务中手动捕获异常,居然判定回滚了,这是什么操作?话不多说直接上代码 @Service p...
    99+
    2024-04-02
  • Redis事务为什么不支持回滚
    目录前言Redis 有事务吗Redis 事务实现原理Redis 事务 ACID 特性A - 原子性 C - 一致性I - 隔离性D - 持久性watch 命令watch 命...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作