Spring-dataSource事务案例分析-使用事务嵌套时,一个我们容易忽略的地方

场景如下:

  • A_Bean 中的方法a()中调用B_Bean的b();
  • 方法都开启了事务,使用的默认的事务传递机制(即:属于同一事务);

如下两种场景会存在较大的差异:

  1. 在b()方法中出现了异常,在b()中进行捕获并处理且没有抛出新的异常,事务最终会进行提交;
  2. 在b()方法中出现了异常,在a()中进行捕获并处理且没有抛出新的异常,那么事务最终会如何呢?—— 先给结论:事务回滚

这个小差异平时编程的过程比较难留意到,会简单认为:当某个方法上面开启了事务,并且当前方法没有抛出任何异常,最终方法上面的事务一定会提交。其实这里是存在认知错误的

code如下:

@SpringBootTest
public class TransactionTest {@Autowiredprivate A a;@Testvoid testTransaction() throws Exception {a.a();}}@Service
public class A {@Autowiredprivate B b;@Transactionalpublic void a() {try {b.b();} catch (Exception e) {log.error("b执行异常,进行捕获且不抛出异常");}// for some db operation}}@Service
public class B {@Transactionalpublic void b() {// for some db operationthrow new RuntimeException("b-error");}
}}

为何错误?

  • 当 a() 方法调用 b() 方法时,如果两个方法都开启了事务且采用默认的事务传播行为(即事务嵌套),b() 方法的事务会加入到 a() 方法的事务中,成为同一个事务。
  • 那么b()中出现异常,b中没有捕获而在a中捕获,实则已经触发b()的事务处理异常的逻辑。
  • 而a、b方法执行又同属一个事务,在b异常被事务管理器感知到后就会将当前事务标记为rollback,那么即使a最终没有感知到异常,最终a正常执行完毕后,a上面的事务管理逻辑也不会将事务进行提交,而是采取回滚的决定!

源码分析

当一个事务方法执行出现异常时(比如b()执行抛出异常时):

org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing

org.springframework.transaction.support.AbstractPlatformTransactionManager#rollback

org.springframework.transaction.support.AbstractPlatformTransactionManager#processRollback

org.springframework.jdbc.datasource.DataSourceTransactionManager#doSetRollbackOnly

org.springframework.jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setRollbackOnly

org.springframework.transaction.support.ResourceHolderSupport#setRollbackOnly

当a()正常执行完毕,准备提交事务时:

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning

org.springframework.transaction.support.AbstractPlatformTransactionManager#commit

org.springframework.transaction.support.SmartTransactionObject#isRollbackOnly

org.springframework.jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#isRollbackOnly

a执行完毕会进行判断:

最终还是会进行事务的回滚!

在 Spring 中,当事务被标记为 rollback-only 时,它会通知事务管理器,表示事务应该回滚。即使没有抛出新的异常,一旦事务被标记为 rollback-only,最终事务仍然会回滚。

因此,在你的情况下,如果 b() 方法中出现异常,在 a() 方法中进行了捕获并处理,但是事务在 b() 方法中被标记为 rollback-only,最终会导致 a() 方法的事务回滚。

如果有这种需要该如何处理?

如题:a事务嵌套b事务,不管b事务是否执行成功,只有a中最终没有抛出异常那么就需要将a提交,做到a事务不受内部嵌套事务的影响,该如何?

修改b事务的传播配置:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库主从备份

1、简介 数据库运⾏时,⼀些因素可能会导致服务运⾏不正常,⽤户访问数据受阻。对于互联⽹公 司,尤其是购物⽹站⽽⾔,这种情况造成的损失是⽆法估量的。因此,对数据库进⾏“备份” 也是必不可少的操作。当主要的数据库死…

MediaStream使用webRtc多窗口传递

最近在做音视频通话,有个需求是把当前会话弄到另一个窗口单独展示,但是会话是属于主窗口的,多窗口通信目前不能直接传递对象,所以想着使用webRtc在主窗口和兄弟窗口建立连接,把主窗口建立会话得到的MediaStream传递给兄…

Unity之XR Interaction Toolkit如何在VR中实现渐变黑屏效果

前言 做VR的时候,有时会有跳转场景,切换位置,切换环境,切换进度等等需求,此时相机的画面如果不切换个黑屏,总会感觉很突兀。刚好Unity的XR Interaction Toolkit插件在2.5.x版本,出了一个TunnelingVignette的效果,我们今天就来分析一下他是如何使用的,然后我们自己再来…

MAC电脑M1安装OpenCV

最近在学习研究OpenCV,奈何只有mac电脑。安装OpenCV感觉还是挺麻烦的,所以记录一下,难免以后会忘记。 安装OpenCV我参考的帖子 https://www.bilibili.com/read/cv23613225/ 一、首先安装Anaconda 目前已安装不做赘述 二、启动命令窗口 方…

ArcGIS无法链接在线地图或错误: 代理服务器从远程服务器收到了错误地址(验证服务器是否正在运行)。

这几天我们分享了! 谷歌卫星影像图归来!ArcGIS直连!快来获取_谷歌影像lyr-CSDN博客文章浏览阅读666次,点赞11次,收藏9次。大概。_谷歌影像lyrhttps://blog.csdn.net/kinghxj/article/details/137521877一套图源搞定&a…

【办公类-22-04】20240418 UIBOT模拟上传每天两篇,获取流量券,并删除内容

背景需求: 前文制作了用UIBOT获取CSCN的3天、5天、7天、12天奖励流量券, 【办公类-22-03】20240417 UIBOT模拟上传获取流量券,并删除内容-CSDN博客文章浏览阅读253次,点赞6次,收藏3次。【办公类-22-03】20240417 UIB…

详解运算符重载,赋值运算符重载,++运算符重载

目录 前言 运算符重载 概念 目的 写法 调用 注意事项 详解注意事项 运算符重载成全局性的弊端 类中隐含的this指针 赋值运算符重载 赋值运算符重载格式 注意点 明晰赋值运算符重载函数的调用 连续赋值 传引用与传值返回 默认赋值运算符重载 前置和后置重载 前…

华为OD机试 - 分披萨 - 动态规划(Java 2024 C卷 200分)

华为OD机试 2024C卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷C卷)》。 刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试…

抖去推短视频矩阵系统----源头开发

为什么一直说让企业去做短视频矩阵?而好处就是有更多的流量入口,不同平台或账号之间可以进行资源互换,最终目的就是获客留咨,提单转化。你去看一些做得大的账号,你会发现他们在许多大的平台上,都有自己的账…

HTML5 <video> 标签属性、API 方法、事件、自定义样式详解与实用示例

HTML5 <video> 标签为网页内嵌视频提供了强大且便捷的功能。以下是对 <video> 标签的主要属性、API 方法、事件、自定义样式及其使用示例的详细介绍&#xff1a; 一、属性 1. src 定义&#xff1a;指定视频文件的 URL。示例&#xff1a;<video src"my_v…

【C++杂货铺】继承

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 继承的概念和定义 &#x1f4c2; 概念 &#x1f4c2; 定义 &#x1f4c1; 基类和派生类对象赋值转换 &#x1f4c1; 继承中的作用域 &#x1f4c1; 派生类的默认成员函数 构造函数 析构函数 拷贝构造函数 赋值重载…

有公网IP,如何设置端口映射实现访问?

很多中小型公司或个人会根据自身需求自建服务器&#xff0c;或者将自己内网的服务、应用发布到外网&#xff0c;实现异地访问&#xff0c;如远程桌面、网站、数据库、公司的管理系统、FTP、管家婆、监控系统等等。 没接触过的人可能会觉得这个很难&#xff0c;实际上使用快解析…

Golang插件系统实现

插件可以在解耦的基础上灵活扩展应用功能&#xff0c;本文介绍了如何基于Golang标准库实现插件功能&#xff0c;帮助我们构建更灵活可扩展的应用。原文: Plugins with Go 什么是插件 简单来说&#xff0c;插件就是可以被其他软件加载的软件&#xff0c;通常用于扩展应用程序的功…

[入门]测试层级-ApiHug准备-测试篇-005

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace 这里的测…

学习STM32第十五天

SPI外设 一、简介 STM32F4XX内部集成硬件SPI收发电路&#xff0c;可以由硬件自动执行时钟生成、数据收发等功能&#xff0c;减轻CPU负担&#xff0c;可配置8位/16位数据帧&#xff0c;高位&#xff08;最常用&#xff09;/低位先行&#xff0c;三组SPI接口&#xff0c;支持DMA…

第一篇【传奇开心果系列】我和AI面对面聊编程:深度比较PyQt5和tkinter.ttk

传奇开心果系列博文 系列博文目录我和AI面对面聊编程系列 博文目录前言一、今天我们面对广大读者选择PyQt5和tkinter.ttk做比较这个话题目的是什么&#xff1f;二、举一个最简单的pyqt5信号和插槽的例子三、这和tkinter的点击事件有什么区别&#xff1f;四、如何选择&#xff1…

MySQL Explan执行计划详解

Explan执行计划 首先我们采用explan执行计划 执行一条sql&#xff0c;发现返回了12个列&#xff0c;下面会详细解释每一列 1、ID列 id列的值是代表了select语句执行顺序&#xff0c;是和select相关联的&#xff1b;id列的值大的会优先执行&#xff0c;如果id列为空最后执行&a…

数据库的创建

数据库分类 通过查看对象资源管理器来区分数据库类型 数据库物理文件的组成 : 数据库文件 日志文件 创建一个主数据文件和一个日志文件

上线流程及操作

上节回顾 1 搜索功能-前端&#xff1a;搜索框&#xff0c;搜索结果页面-后端&#xff1a;一种类型课程-APIResponse(actual_courseres.data.get(results),free_course[],light_course[])-搜索&#xff0c;如果数据量很大&#xff0c;直接使用mysql&#xff0c;效率非常低--》E…

淘宝商品数据抓取新策略:API接口助力获取标题、分类与店铺名

随着电子商务的迅猛发展&#xff0c;淘宝作为中国最大的网络购物平台&#xff0c;其商品数据对于众多商家、研究者和市场分析师来说具有极高的价值。然而&#xff0c;如何高效、准确地抓取淘宝商品数据&#xff0c;尤其是商品标题、分类和店铺名等关键信息&#xff0c;一直是一…