我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么使用@Transactional设置嵌套事务不回滚

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么使用@Transactional设置嵌套事务不回滚

本篇内容介绍了“怎么使用@Transactional设置嵌套事务不回滚”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

@Transactional 设置嵌套事务不回滚

@Transactional(rollbackFor = Exception.class)    public void testA(RequestSchedulingVO requestSchedulingVO) {     ...业务...        BService.testB(param);    }
@Override    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, noRollbackFor = BusinessException.class)//    @Transactional(propagation = Propagation.NOT_SUPPORTED)    public void testB(Long param) throws BusinessException {        ...业务...        try{        }cach(Exception e){         throw new BusinessException(BaiduFaceErrorCode.FACE_CREATE_CONVERSATION_ERROR);        }    }

这里的事务要求是方法testB报错(BusinessException异常)时,testB事务不回滚,testA事务回滚.

方案一:

testB设置事务为REQUIRES_NEW(创建一个新的事务,如果当前存在事务,则把当前事务挂起),并设置不回滚的异常类

方案二:

testB设置事务为NOT_SUPPORTED(以非事务方式运行,如果当前存在事务,则把当前事务挂起)。

@Transactional回滚问题(try catch、嵌套)

Spring 事务注解 @Transactional 本来可以保证原子性,如果事务内有报错的话,整个事务可以保证回滚,但是加上try catch或者事务嵌套,可能会导致事务回滚失败。测试一波。

准备

建两张表,模拟两个数据操作

CREATE TABLE `user` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(20) DEFAULT NULL,  `age` smallint(3) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; CREATE TABLE `role` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `role_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

测试

根据排列组合原理,我们进行四种测试:1、无try catch、无嵌套;2、有try catch、无嵌套;3、无try catch、有嵌套;4、都有。

最简单测试

如果我们单纯@Transactional,事务可以正常回滚吗?

@GetMapping("/saveNormal0")    @Transactional    public void saveNormal0() throws Exception {        int age = random.nextInt(100);        User user = new User().setAge(age).setName("name:"+age);        userService.save(user);        throw new RuntimeException();    }

如果事务内报了RuntimeException错误,事务可以回滚。

@GetMapping("/saveNormal0")    @Transactional    public void saveNormal0() throws Exception {        int age = random.nextInt(100);        User user = new User().setAge(age).setName("name:"+age);        userService.save(user);        throw new Exception();    }

如果事务内报了Exception错误(非RuntimeException错误),事务不可以回滚。

@GetMapping("/saveNormal0")    @Transactional( rollbackFor = Exception.class)    public void saveNormal0() throws Exception {        int age = random.nextInt(100);        User user = new User().setAge(age).setName("name:"+age);        userService.save(user);        throw new Exception();    }

如果是Exception错误(非RuntimeException),加上 rollbackFor = Exception.class 参数也可以实现回滚。

结论一:对于@Transactional可以保证RuntimeException错误的回滚,如果想保证非RuntimeException错误的回滚,需要加上rollbackFor = Exception.class 参数。

try catch 影响

经过博主多种情况测试,发现try catch对回滚这个事本身没有什么影响,结论一照样成立。try catch只是对异常是否可以被@Transactional 感知 到有影响。如果错误抛到切面可以感知到的地步,那就可以起作用。

@GetMapping("/saveTryCatch")    @Transactional( rollbackFor = Exception.class)    public void saveTryCatch() throws Exception{        try{            int age = random.nextInt(100);            User user = new User().setAge(age).setName("name:"+age);            userService.save(user);            throw new Exception();        }catch (Exception e){            throw e;        }    }

比如上面一段代码就回滚了。

@GetMapping("/saveTryCatch")    @Transactional( rollbackFor = Exception.class)    public void saveTryCatch() throws Exception{        try{            int age = random.nextInt(100);            User user = new User().setAge(age).setName("name:"+age);            userService.save(user);            throw new Exception();        }catch (Exception e){        }    }

然而,将catch中的错误不继续网上抛,切面无法感知到错误,无法进行处理,那么事务就无法回滚了。

结论二:try catch只是对异常是否可以被@Transactional 感知 到有影响。如果错误抛到切面可以感知到的地步,那就可以起作用。

事务嵌套 影响

首先经过实验,结论一仍然成立,即,当不加上rollbackFor = Exception.class 的时候,无论内外报RuntimeException,都会回滚;无论内外报 非RuntimeException 错误,都不会回滚。如果加上rollbackFor = Exception.class,无论内外怎么报错,都会回滚。这些代码就不给出了。接下来,试下下面两种情况:

   @GetMapping("/out")    @Transactional( rollbackFor = Exception.class)    public void out() throws Exception{        innerService.inner();        int age = random.nextInt(100);        User user = new User().setAge(age).setName("name:" + age);        userService.save(user);        throw new Exception();    }    @Transactional    public void inner() throws Exception{        Role role = new Role();        role.setRoleName("roleName:"+new Random().nextInt(100));        roleService.save(role);//        throw new Exception();    }

情况一,外面事务加上rollbackFor = Exception.class,里面事务不加,测试内外分别报错的情况(为了简化代码量,只给出了外面报错的代码),都可以回滚。因为,无论如何,错误都抛给了外面那个事务进行处理,而外面那个加上了rollbackFor = Exception.class,具备处理非RuntimeException错误的能力,所以都可以让事务进行正常回滚。

下面看情况二,里面的事务加上rollbackFor = Exception.class,外面不加,外面报错。

   @GetMapping("/out")    @Transactional    public void out() throws Exception{        innerService.inner();        int age = random.nextInt(100);        User user = new User().setAge(age).setName("name:" + age);        userService.save(user);        throw new Exception();    }        @Transactional( rollbackFor = Exception.class)    public void inner() throws Exception{        Role role = new Role();        role.setRoleName("roleName:"+new Random().nextInt(100));        roleService.save(role);    }

事务都无法回滚,这是我们有个疑问,里面的事务明明有很强的处理能力啊,为什么和外面一起回滚失败呢,别着急,等等聊这个。

然后试下里面报错:

@GetMapping("/out")    @Transactional    public void out() throws Exception{        innerService.inner();        int age = random.nextInt(100);        User user = new User().setAge(age).setName("name:" + age);        userService.save(user);    }     @Transactional( rollbackFor = Exception.class)    public void inner() throws Exception{        Role role = new Role();        role.setRoleName("roleName:"+new Random().nextInt(100));        roleService.save(role);        throw new Exception();    }

咦,这回都进行了正常的回滚。我的天,这回外面没有处理能力,为什么接受里面抛出来的错误,也进行了回滚!!!看上去,就好像里外事务总是同生共死的对不对?原来,@Transactional还有个参数,看下源码,这个注解还有默认值:

Propagation propagation() default Propagation.REQUIRED;

REQUIRED的意思是说,事务嵌套的时候,如果发现已经有事务存在了,就加入这个事务,而不是新建一个事务,所以根本就不存在两个事务,一直只有一个!至于,此参数其他值,本文不进行测试。回到上面的问题,当外面报错的时候,此时查看事务,没有增加rollbackFor = Exception.class参数,即没有处理非RuntimeException能力,所以代码走完,貌似“两个事务”,都回滚失败了。当里面报错的时候,事务已经添加上了处理非RuntimeException能力,所以,代码走完就回滚成功了。

结论三:由于REQUIRED属性,“两个事务”其实是一个事务,处理能力看报错时刻,是否添加了处理非RuntimeException的能力。

try catch和事务嵌套 共同影响

在结论一二三成立的条件下,探索共同影响的问题就简单多了,由于情况太多,就不进行过多的代码展示了。

结论

结论一:

对于@Transactional可以保证RuntimeException错误的回滚,如果想保证非RuntimeException错误的回滚,需要加上rollbackFor = Exception.class 参数。

结论二:

try catch只是对异常是否可以被@Transactional 感知 到有影响。如果错误抛到切面可以感知到的地步,那就可以起作用。

结论三:

由于REQUIRED属性,“两个事务”其实是一个事务,处理能力看报错时刻,是否添加了处理非RuntimeException的能力。

“怎么使用@Transactional设置嵌套事务不回滚”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么使用@Transactional设置嵌套事务不回滚

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么使用@Transactional设置嵌套事务不回滚

本篇内容介绍了“怎么使用@Transactional设置嵌套事务不回滚”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!@Transaction
2023-06-20

怎么在Spring中利用@Transactional实现事务回滚

今天就跟大家聊聊有关怎么在Spring中利用@Transactional实现事务回滚,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、使用场景举例在了解@Transactional怎
2023-05-30

华为云服务器密码怎么设置不了呢怎么回事

如果您无法设置华为云服务器的密码,请检查以下几个方面:检查您的网络是否正常:网络是否正常会影响服务器的运行,因此建议检查您的网络连接,确保其正常。重置密码:确保您的密码已经更改,并且已经成功重置。可以通过在华为云服务网站上找到您的账户或联系华为云官方客服以获取更多信息。检查您的证书和密钥:确保您的证书和密钥已正确地管理,并且没有被任何人窃取,因为这会导致您无法使用服务器。检查网络设置:
2023-10-26

腾讯云服务器ipv6设置不了密码怎么回事

首先,我们需要了解ipv6的概念。ipv6是"ipv6地址"的缩写,它是一种通用的地址格式,是一种IPv4地址向IPv6地址过渡的技术。IPv6地址是22位二进制数,由0和1组成,每8位为1组,表示4个地址族,包含24个8位的IP地址。ipv6的设置需要考虑以下几个方面:设置IPv6地址:IPv6地址是通过路由器来分配
2023-10-27

华为云服务器密码怎么设置不了呢怎么回事儿

1.密码设置问题1.1密码长度在设置华为云服务器密码时,需要注意密码长度的限制。华为云服务器密码长度必须在8-26个字符之间,且必须包含大小写字母、数字和特殊字符中的至少三种。如果您的密码不符合这些要求,系统将无法接受您的密码设置。1.2特殊字符另外,华为云服务器密码中的特殊字符也需要注意。在设置密码时,建议使用常见的特殊字符,如@、#、$、%等。如果您使用了过于复杂或不常见的特殊字符,
2023-10-26

轻量应用服务器流量不足怎么回事呢苹果13怎么设置

轻量应用服务器流量不足是由于服务器网络连接速度较慢,导致应用程序无法正常运行,从而导致AppStore网站访问缓慢、下载缓慢,以及用户在购买App时无法进行支付。为了解决这种情况,您需要检查服务器网络连接速度,以确保其始终是畅通的。您可以使用以下步骤:重启您的服务器连接:在使用Windows操作系统和苹果手机时,请尝试在设置中启用“自动连接到Internet”选项,以便在您停用网络连接时自
2023-10-26

腾讯云服务器密码规则怎么设置不了呢怎么回事

在使用腾讯云服务器的过程中,可能会遇到密码规则设置不了的情况,这是由于该规则的规则不符合腾讯云服务器的要求,需要进行修改或者重新设置。如果无法解决该问题,可以尝试以下方法:修改密码规则:在腾讯云服务器的控制台中点击“设置”按钮,然后找到“安全组”选项,点击进入安全组设置页面,找到“密码规则”,在“密码规则设置”页面中修
2023-10-27

轻量应用服务器端口用不了怎么回事儿呀苹果13怎么设置

如果您的应用服务器端口正在使用其他端口,可能会导致无法连接到您的iOS设备。请联系您的应用开发商或应用程序提供商以获取正确的端口选择。如果您无法使用应用服务器端口,可以尝试以下几个步骤:检查应用程序的源代码,确定是否有任何端口或其他协议可能与应用程序的通信。检查应用程序的用户设置或库设置,确保它们已正确配置。检查应用程序与其他服务的依赖项,确保它们都正确安装。如果依赖项不存在,请将其添加
2023-10-26

云服务器监控别的设备能看吗怎么设置不了呢怎么回事

查看当前系统运行情况首先,你可以通过云服务器的控制面板来查看云服务器的系统运行情况,可以在控制面板中找到“系统”选项,然后点击“性能监视器”,可以查看当前系统的运行情况。你也可以在“系统和维护”选项中找到“系统监视器”,可以查看系统的性能指标。查看系统日志在云服务器的系统日志中,你可以查看到云服务器的所有操作记录,包括
云服务器监控别的设备能看吗怎么设置不了呢怎么回事
2023-10-28

轻量应用服务器登录不了怎么回事呢苹果手机怎么设置

如果您的应用服务器登录失败,那么很可能是由于您的手机系统版本过旧或者操作系统权限不足引起的。以下是一些可能有帮助的解决方案:1.尝试升级您的操作系统或更换新操作系统:如果您的操作系统版本过旧或者系统权限不足,那么尝试升级您的系统或更换新操作系统可能会解决登录问题。在升级之前,请确保您的手机已经更新到最新版本的操作系统。2.检查您的手机是否被恶意软件感染:有时,应用程序服务器可能会出现问题或者
2023-10-26

轻量应用服务器登录不上怎么回事呢苹果手机怎么设置

轻量应用服务器(LightweightApplicationServer,LSP)是一种轻量级的应用服务器,它能够支持各种应用,包括Web、游戏、数据库和云服务等。轻量应用服务器通常具有以下特点:支持多种应用程序:轻量应用服务器能够支持各种应用程序,包括Web应用程序、游戏、数据库应用程序和其他轻量级应用,同时还可以与其他轻量级应用服务器进行集成。轻量化设计:轻量应用服务器采用了轻量化的设
2023-10-26

轻量应用服务器登录不了怎么回事呀苹果手机怎么设置

轻量应用服务器登录不了可能有多种原因导致,以下是一些可能的解决方法:1.检查网络连接:尝试重新检查网络连接,确保连接正确并尝试使用网络。确保连接稳定,并且网络设置正常。2.检查用户名和密码:如果登录时需要输入用户名和密码,请确保用户名和密码的安全性。可以使用强密码或密码生成器等方式来解决这些问题。3.检查应用程序:检查应用程序是否被正确安装,并且安装的路径是否正确。如果应用程序未正常安装或
2023-10-26

轻量应用服务器流量不足怎么回事呀苹果手机怎么设置

一、合理设置应用程序服务器配置文件应用程序服务器配置文件是应用程序在运行时所需要的资源。合理设置应用程序服务器配置文件可以有效提高应用程序的性能和数据传输速度。在应用程序服务器配置文件中,我们可以添加一些限制性的配置项,如CPU使用率、内存使用率、网络带宽等。这些配置项可以根据应用程序的运行情况进行动态调整,以达到优化
轻量应用服务器流量不足怎么回事呀苹果手机怎么设置
2023-10-28

轻量应用服务器登录不上怎么回事呀苹果手机怎么设置

轻量应用服务器登录不上可能有多种原因导致,以下是一些可能的解决方法:1.尝试重新启动应用程序:首先,尝试重新启动应用程序或尝试清除浏览器缓存,以便重新加载登录页面。如果仍然无法解决问题,请尝试在安全模式下重新启动应用程序或清除浏览器缓存。2.使用新的浏览器或软件:有时,您可能会发现应用程序或浏览器没有正确更新,导致您无法访问您的账户。尝试升级或更新您的应用或浏览器以满足最新版本的要求。3.
2023-10-26

轻量应用服务器流量不足怎么回事呢苹果手机怎么设置

轻量应用服务器流量不足是由于多种原因引起的,以下是一些可能的解决方案:应用程序内存不足:请确保应用程序能够快速访问您的数据,并避免在不需要的情况下保存过多的用户数据。网络连接问题:请确保您的网络连接正常,并确保您的电脑有足够的带宽来处理您需要的数据。如果您使用较慢的网络,请尝试使用其他网络。应用程序崩溃:请确保您的应用程序能够正常运行,并且不会崩溃以致影响其他应用程序。系统更新失败:您
2023-10-26

轻量应用服务器流量不足怎么回事呢苹果12手机怎么设置

轻量应用服务器流量不足是由于苹果手机的一些应用程序或服务在使用时需要更多的网络带宽和加速器。在这种情况下,您可以尝试以下步骤:重新启动手机:如果您的iPhone无法重新启动,请尝试重新启动手机并等待几分钟,这将有助于减少数据流量消耗,同时使应用程序的加速器更为流畅。手动调整应用程序的网络设置:一些应用程序可能会使用特定的网络设置,例如Wi-Fi或蜂窝数据。您可以手动对这些设置进行调整以确保您的应用程序能够通过所需...
2023-10-26

轻量应用服务器登录不了怎么回事呀苹果13手机怎么设置

如果您的应用服务器登录失败,那么很可能是因为您的手机设置了不正确的权限。如果您想设置您的应用服务器为允许登录状态,以下是可能的解决方案:检查您的设置。您可以按照以下步骤检查您的设置是否正确:进入应用程序,然后按照屏幕上的提示来更改您的设置。如果您遇到了错误消息,请返回应用程序并按照屏幕上的提示进行操作。检查您的账户和密码。您可能已经忘记了您的账户和密码并且无法通过应用程序或网站来访问它们。
2023-10-26

轻量应用服务器登录不上怎么回事呢苹果13手机怎么设置

对于轻量应用服务器登录不上的问题,可能有多种原因导致,以下是一些可能的解决方法:检查网络连接:确保您的设备已连接到互联网,并且网络连接稳定。您可以尝试使用其他设备连接到同一网络,以确定问题是否出在您的设备上。检查服务器状态:如果您无法登录到轻量应用服务器,可能是服务器出现了问题。您可以尝试联系服务器管理员或者查看服务器状态是否正常。检查登录凭证:确保您输入的用户名和密码是正确的,并且没有
2023-10-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录