当前位置: 首页 > ds >正文

Spring事务开发经验 回滚和不回滚?

关于Spring事务原理的知识可以看我的一篇文章:Spring事务原理 如何增强、回滚、提交。那么在明白事务原理之后,工作中使用Spring事务控制时候需要注意什么?我根据工作经验列出几个注意点:

  1. 开启事务需要经过代理对象调用
  2. 避免长事务,容易导致死锁和锁超时
  3. 嵌套事务间发生异常是回滚还是不回滚?

本文针对第3个问题配合源码和实验例子说明,什么情况下抛出异常事务回滚。Spring 事务中 catch 异常后会回滚吗?有2种说法:

  1. 如果事务中 catch 了异常并且不抛出,事务不会回滚。
  2. 如果事务中 catch 了异常,但是事务依然回滚。

以下实验均是基于 read commited隔离级别,SpringBoot 2.5.6版本。

单个service,单个事务方法内catch异常

实验结论:在catch完后不再重新抛出情况下,事务不受影响,成功提交

双 service 配合,双方法同事务,catch异常

在抛出异常的方法体外catch,让Spring框架感知到异常

A函数 UserService,开启一个事务

B函数 ComodityService,融入当前事务中

实验结论:整体事务失败回滚,出现 Transaction silently rolled back because it has been marked as rollback-only

在抛出异常的方法体内catch异常,让Spring框架感知不到异常

实验结论:整体事务执行成功,包括insertTest() insertB(),2条数据都插入成功。

双 Service 双函数、双事务,catch异常

这个实验和上面实验最核心区别是开启了双事务,一个大事务和一个小事务,两个事务是独立的

A函数,UserService插入user。B函数插入goods,CommodityService 开启新事务,此时是通过代理类调用的所以新事务生效。

insertGoods方法开启新事务,虽然也是在方法内抛出异常让Spring框架感知到了,但是并不影响外层insertUser事务。 

实验结论:A函数事务执行成功,B函数的事务执行失败回滚。

怎么解释这个现象?看日志,B函数开启了一个新事务,挂起了A事务。

B事务执行失败回滚后,Spring恢复了挂起的A事务继续执行,最后成功提交。由此可以推理出,Transaction silently rolled back because it has been marked as rollback-only

只会出现在多个代理对象的同个事务内函数嵌套执行时的情况,当某个方法抛出异常,由于是在同个事务内就算你catch了异常,偷偷消化了。但是被Spring感知到了,根据原子性原则,由于同个事务所有操作必须一起成功或失败,所以Spring选择回滚整体事务!

如果是同个代理对象内的多个函数嵌套执行,虽然也在同个事务内但后续的调用链都是基于目标对象this方法内调用没有走代理,所以异常是不会被Spring感知到的(除非第一个开启事务的函数抛出异常被Spring感知到),所以事务不会回滚。

 

http://www.xdnf.cn/news/3134.html

相关文章:

  • ADS1299模拟前端(AFE)代替芯片——LHE7909
  • C事件驱动网络库​​libevent的http详解
  • Java实现使用EasyExcel按模板导出文件
  • 【Unity】使用LitJson保存和读取数据的例子
  • SQL注入
  • Leetcode 3533. Concatenated Divisibility
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第四模块·Java特性专精 —— 第十七章 IO流:超越FILE*的维度战争
  • SpringBoot之SpringAl实现AI应用-快速搭建
  • LeetCode -160.相交链表
  • “假读“操作在I2C接收流程中的原因
  • DECAP CELL
  • Qt入门——什么是Qt?
  • 【Linux】第十三章 访问Linux文件系统
  • React:封装一个编辑文章的组件
  • python如何流模式输出
  • Missashe考研日记-day30
  • JR6001语音模块详解(STM32)
  • 1.3 点云数据获取方式——ToF相机
  • Linux电源管理(3)_关机和重启的过程
  • 【今日三题】小红的ABC(找规律) / 不相邻取数(多状态dp) / 空调遥控(排序+二分/滑动窗口)
  • 面向人工智能、量子科技、人形机器人等产业,山东启动制造业创新中心培育认定
  • Android Studio 中实现方法和参数显示一行
  • Git 多账号切换及全局用户名设置不生效问,GIT进行上传无权限问题
  • 科研入门规划
  • computed计算值为什么还可以依赖另外一个computed计算值?
  • linux下ACL权限和掩码权限
  • Springboot2.X 读取多层嵌套的配置结构
  • 【东枫电子】AI-RAN:人工智能 - 无线接入网络
  • react-新建项目复用node_modules
  • 从摄像头到 RAW 数据:MJPEG 捕获与验证