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,一经查实,立即删除!

相关文章

Android 原生功能与 Vue 交互实现

前端用 Android webview 嵌入 vue 地址,如何在vue 页面中显示 Android 版本号 一.要在vue页面中显示Android版本号 从Android中将该信息传递给Vue应用程序。可以通过使用WebView的Java Bridge来实现此目的。这里是一些可能有用的步骤: 在你的Android代…

数据库主从备份

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; 派生类的默认成员函数 构造函数 析构函数 拷贝构造函数 赋值重载…

利用vue3SeamlessScroll 简单实现列表的无限循环滚动

Vue3SeamlessScroll 该组件用于实现列表的无限循环滚动 1、安装 npm i vue3-seamless-scroll 2、导入及基本使用 <!--组件.vue--> <script setup>import { Vue3SeamlessScroll } from vue3-seamless-scroll;import {ref} from vue//vue3导入组件是不需要用com…

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

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

Golang插件系统实现

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

浅谈-“指针”

为什么要使用指针&#xff1f; 1.函数的值传递&#xff0c;无法通过调用函数&#xff0c;来修改函数的实参 2.被调用函数需要提供更多的“返回值”给调用函数 3.减少值传递时带来的额外开销&#xff0c;提高代码执行效率 ---> int a[10] > 40 字节 int *p; pa;…

Spring Boot 打印 Controller 返回的body数据

背景是获取Controller类输出的结果数据。 实现方案&#xff0c;使用RestControllerAdviceResponseBodyAdvice接口。不能使用Interceptor&#xff0c;在执行Interceptor时&#xff0c;response已经提交。也可以考虑aspect方案&#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 这里的测…

WebKit结构深度解析:打造高效与安全的浏览器引擎

WebKit结构深度解析&#xff1a;打造高效与安全的浏览器引擎 在现代网络世界中&#xff0c;浏览器作为连接用户与互联网信息的桥梁&#xff0c;其背后的技术架构至关重要。WebKit&#xff0c;作为当今最流行的开源浏览器引擎之一&#xff0c;其结构设计和功能实现对于提升浏览…

统一SQL-number/decimal/dec/numeric转换

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 通过统一SQL&#xff0c;将Oracle中的numb…