【SpringBoot实践】事务和事务传播机制失效原因正确使用事务的建议

文章目录

  • 1.概述
  • 2.事务与事务传播
    • 2.1 声明式事务说明
    • 2.2.声明式事务失效原因
    • 2.3.事务的传播机制
    • 2.4.事务传播失效原因
  • 3.事务使用建议
  • 4.总结

1.概述

我们在开发工作中经常会使用到事务,来保证数据库做增、删、改操作时的数据一致性,在使用Spring来处理事务的时候,如果没有正确的使用就很易容出现事务失效或者事务传播失效的问题,导致预期结果与实际结果不符。
为了彻底解决这种“一不小心”出现的事务失效问题,今天就结合理论和代码实践,验证一下什么情况下会导致事务失效,并总结如何正确的使用事务。

注:本篇验证的事务机制为使用@Transactional注解的声明式事务。

2.事务与事务传播

在做验证之前,需要对Spring中两个容易混淆的概念:事务和事务传播。

  • 事务:一种保持数据一致性的机制,具有ACID的特征。
  • 事务传播:Spring对不同方法的声明式事务组合起来使用,根据组合方式的不同,得到不一样的结果。

2.1 声明式事务说明

下面会简单的说明一下Spring中声明式事务的实现原理,不过在这之前先了解一下编程式事务,这是声明式事务的基础,下面是一个简化的Demo代码:

@Autowired
private PlatformTransactionManager transactionManager;public void performSomeBusinessLogic() {TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// 执行业务逻辑// 事务提交transactionManager.commit(status);} catch (Exception ex) {// 事务回滚transactionManager.rollback(status); throw ex;}
}

我们可以使用PlatformTransactionManagerTransactionDefinitionTransactionStatus 这3个API完成编程式事务。


对于声明式事务来说,我们通过给方法打上一个@Transactional注解,就可以让这个方法以事务的方式来运行,而这种方式在Spring中往往是通过AOP来实现的,将@Transactional注解作为切点,进入一个处理事务的切面,这个切面里面要做的事就是开启事务,执行业务逻辑,判断事务是提交还是回滚。可以简单的理解为编程式事务那一套代码放到了通过AOP生成代理对象中了

2.2.声明式事务失效原因

既然是代理对象实现的,那就可以得出一个结论:如果AOP失效,那么声明式事务也会失效,于是我们可以发现事务失效的几个原因:

  1. 被声明的方法是非public方法、final方法、静态方法
  2. 对象内部自调用

对第2点,假设当前对象中有两个方法分别是a和ba上面没有写@Transactionalb上面写了,此时在a方法中使用this.b()来发起调用,这种情况下调用的是b的实例方法,并不是代理对象中的方法,没有代理自然事务就失效了,这也是下面会提到的事务传播失效的原因。

如果不想把两个方法放到两个不同的类中,可以在a方法中通过applicationContext.getBean(this.getClass());再获取一次代理对象,这样就不会失效了。


除此之外,再看一下上面的代码,事务会在catch块中调用rollback方法进行回滚,如果在业务流程中处理了异常没有向上抛出到代理对象中,就不会触发rollback,导致事务的回滚失效,因此我们可以得出事务失效的另一个原因:

  1. 异常被业务代码逻辑捕获,没有向上抛出到代理对象中

针对这个失效原因,需要补充一点的是,在某些场景下我们可能会通过切面对Service层通过AOP做统一异常处理,这种情况也可能会导致异常没有抛出到事务相关的代理对象中,导致回滚失效,这种情况隐藏的比较深,可能不容易排查到。


除了AOP层面导致的事务失效以外,我们再把视线集中的@Transactional本身上面,在这个注解有两个重要的配置,事务传播配置(Propagation)回滚异常配置(rollbackFor),这两个配置错误也可能导致事务失效。

  1. 配置了不支持事务的事务传播类型
  2. 需要回滚的异常类型未正确配置

对与第4点,下面的内容还会详细描述,这里说明一下回滚异常配置。
Transactional这个注解类中,对于rollbackFor有这么一段注释:
在这里插入图片描述
意思是说,未显式的指定回滚异常时,只要在抛出的异常为RuntimeException或者抛出的是Error时才会回滚,而其他的受检异常是不会回滚的。


最后,就是数据库本身的问题:

  1. 数据库引擎不支持事务(废话)

2.3.事务的传播机制

事务传播是多个带有事务的方法在组合使用时,希望通过配置不同的传播机制来达到不同的结果,Spring中定义的事务传播的配置一共有7种,分别是:

  • REQUIRED:多个方法在同一个事务下运行,其中有任一报错,都会一起回滚。
  • REQUIRED_NEW:调用时会新开一个事务,则多个方法在不同事务中运行,各自的方法报错只会回滚自己,互相不影响。
  • SUPPORT:被调用的方法会加入调用者的事务,如果调用者没有事务,则非事务运行。
  • NOT_SUPPORTED:如果调用者有事务,则暂停该事务,被调用方法以非事务运行。
  • MANDATORY:强制必须有事务,如果没有则抛出异常。
  • NESTED:多个方法属于同一个事务,但被调用方法的事务属于调用者的子事务。
  • NEVER:强制必须没有事务,如果有则抛出异常。

这里主要说一下NESTED,这是一种嵌套事务,与REQUIRED不同的是,被调用方法报错会将事务回滚到一个savePoint,不会引起调用者事务回滚,与REQUIRED_NEW不同的是,如果调用者出现了异常,也会带着被调用者一起回滚。

另外,在项目中使用事务传播机制,还得考虑一下数据库的隔离等级,两者配合很可能会给你带来死锁大礼包,举个简单的例子:用REQUIRED_NEW做事务传播,调用者和被调用者都update同一行数据使用id作为条件,调用者再等待被调用者执行完毕,被调用者再等待调用者完成事务,互相等待导致死锁。

2.4.事务传播失效原因

其实在上面事务失效中已经提到了,事务失效肯定传播也会失效,但这里需要强调的是。最容易忽略的原因还是因为使用的对象的自调用。
我们在编写项目的时候,很多情况下两个方法就是放在同一个service对象中的,不经意间就通过this.xxx进行调用了,然后一看就发现事务传播失效了。

3.事务使用建议

在条件允许的情况下,通过编程式事务来替换声明式事务可以有效的避免事务失效,并且可以更细粒度的控制事务,但缺点也比较明显,在业务逻辑中侵入了太多非业务逻辑的代码。

如果一定要使用声明式事务,根据上面提到的一些原因总结一下正确使用事务的几条建议:

  1. 使用public权限来定义方法,不要static,不要final
  2. 异常一定要向上抛出,即使逻辑内部要做异常处理,也需要抛出一个自定义异常
  3. 显式的配置Transactional中的事务传播和回调异常,不要使用默认配置
  4. 只要涉及到多个事务方法的调用,要注意自调用问题,一定要使用代理对象来调用

4.总结

本篇主要是描述了Spring的事务实践中导致事务失效的问题以及正确使用事务的建议,最后将事务失败的原因罗列在这里,方便后续查阅:

  1. 被声明的方法是非public方法、final方法、静态方法
  2. 对象内部自调用
  3. 异常被业务代码逻辑捕获,没有向上抛出到代理对象中
  4. 配置了不支持事务的事务传播类型
  5. 需要回滚的异常类型未正确配置
  6. 数据库引擎不支持事务(废话)

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2023智慧云打印小程序源码多店铺开源版 +前端

智慧自助云打印系统/智慧云打印小程序源码 前端 这是一款全新的基于Thinkphp的最新自助打印系统,最新UI界面设计的云打印小程序源码

单目标应用:基于螳螂搜索算法(Mantis Search Algorithm,MSA)的微电网优化调度MATLAB

一、螳螂搜索算法 螳螂搜索算法(Mantis Search Algorithm,MSA)由Mohamed Abdel-Basset等人于2023年提出,该算法模拟螳螂独特的狩猎和性同类相食行为。MSA由三个优化阶段组成,包括寻找猎物(探索&#xff09…

【Unity3D赛车游戏制作】开始界面场景搭建

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

13.(开发工具篇github)如何在GitHub上上传本地项目

一:创建GitHub账户并安装Git 二:创建一个新的仓库(repository) 三、拉取代码 git clone https://github.com/ainier-max/myboot.git git clone git@github.com:ainier-max/myboot.git四、拷贝代码到拉取后的工程 五、上传代码 (1)添加所有文件到暂存

Idea引入thymeleaf失败解决方法

报错 Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.Fri Sep 29 09:42:00 CST 2023 There was an unexpected error (typeNot Found, status404). 原因:html没有使用thymeleaf 首先要引入…

14.(开发工具篇github)如何在Github配置ssh key

第一步:检查本地主机是否已经存在ssh key 上图表示已存在。跳第三步 第二步:生成ssh key ssh-keygen -t rsa -C "xxxxxx.com"第三步:获取ssh key公钥内容(id_rsa.pub) cat id_rsa.pub第四步:G…

【开发篇】十二、缓存框架JetCache

文章目录 0、介绍1、JetCache远程缓存2、JetCache本地缓存3、标准配置文件4、JetCache方法缓存注解--Cached5、Cached4、CacheUpdate5、CacheInvalidate6、CacheRefresh7、缓存统计报告 上篇完成了Spring Cache底层技术的各种切换,但各个技术有各自的优缺点&#xf…

UE5 ChaosVehicles载具研究

一、基本组成 载具Actor类名称:WheeledVehiclePawn Actor最原始的结构 官方增加了两个摇臂相机,可以像驾驶游戏那样切换多机位、旋转观察 选择骨骼网格体、动画蓝图类、开启物理模拟 二、SportsCar_Pawn 角阻尼:物体旋转的阻力。数值越大…

3D孪生场景搭建:模型阵列摆放

阵列摆放概念 阵列摆放是指将物体、设备或元件按照一定的规则和间距排列组合的方式。在工程和科学领域中,阵列式摆放常常用于优化空间利用、提高效率或增强性能。 阵列摆放通常需要考虑间距、角度、方向、对称性等因素,以满足特定的要求和设计目标。不同…

同城信息服务源码 本地生活服务小程序源码

同城信息服务源码 本地生活服务小程序源码 功能介绍: 基本设置:网站参数、安全设置、分站管理、支付设置、操作日志、地区设置、公交地铁、国际区号、清理缓存、模板风格、模块管理、域名管理、底部菜单、消息通知、登录设置 其他设置:关键…

Python 基于 Yolov8 + CPU 实现物体检测

目录 一、开发环境 二、安装 Python 基于 Yolov8 物体检测关联库 2.1 打开命令提示符(cmd)或终端,安装库 2.2 关联库安装过程遇到的问题 三、基于 Yolov8 物体检测代码实现(完整) 3.1 Yolov8 物体检测完整代码…

力扣:112. 路径总和(Python3)

题目: 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。 叶子节点…

Flink状态

8.1 Flink中的状态 8.1.1 概述 状态的分类 1)托管状态(Managed State)和原始状态(Raw State) Flink的状态有两种:托管状态(Managed State)和原始状态(Raw State&#…

PICO首届XR开发者挑战赛正式启动,助推行业迈入“VR+MR”新阶段

9月25日,“PICO 2023首届XR开发者挑战赛”(下文简称“挑战赛”)媒体启动会在北京圆满落幕,官方赛事报名通道已于今日开启。据悉,本次挑战赛是PICO首次针对全球开发者举办的大型挑战赛事,旨在与开发者保持连…

redis介绍

一、简介 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,…

从入门到精通:详解SVN版本控制系统的使用方法

从入门到精通:详解SVN版本控制系统的使用方法 一、引言1.1、版本控制的概念和重要性1.2、流行的版本控制系统SVN 二、SVN基础知识2.1、SVN的基本概念和术语解释2.2、SVN的工作原理和架构 三、创建SVN仓库3.1、创建本地仓库3.2、配置访问权限 四、使用SVN进行版本控制…

基于视频技术与AI检测算法的体育场馆远程视频智能化监控方案

一、方案背景 近年来,随着居民体育运动意识的增强,体育场馆成为居民体育锻炼的重要场所。但使用场馆内的器材时,可能发生受伤意外,甚至牵扯责任赔偿纠纷问题。同时,物品丢失、人力巡逻成本问题突出,体育场…

企业如何寻找适合的CRM系统软件

在数字化转型步伐不断加快的今天,CRM软件成为企业必不可少的一项工具。如果您并不清楚如何寻找合适的CRM系统软件?不妨通过下列几点来寻觅。 1.根据CRM系统行业和类别 例如企业重视营销功能,搜寻营销型CRM软件; 企业希望梳理好…

Open3D 进阶(11)使用GMM-Tree算法对点云配准

GMM-Tree算法 一、算法原理1、主要函数2、参考文献二、代码实现三、结果展示1、点云初始位置2、配准后的位置四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、

DevExpress WinForms图表组件 - 直观的数据信息呈现方式!(二)

在上文中(点击这里回顾>>),我们为大家介绍了DevExpress WinForms图表控件的互动图表、图标设计器及可定制功能等,本文将继续介绍DevExpress WinForms图表控件的数据分析、大数据功能等,欢迎持续关注我们哦~ Dev…