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

Spring事务传播行为全解析

好的,@Transactional 注解中的 propagation 属性是定义事务传播行为的关键。它解决了这样一个核心问题:当一个事务方法被另一个事务方法调用时,这两个方法的事务应该如何交互?

Spring 提供了 7 种传播行为,定义在 Propagation 枚举中。下面我将逐一列举并解释它们:


1. Propagation.REQUIRED (默认值)

  • 含义:如果当前存在一个事务,则加入这个事务;如果当前没有事务,则创建一个新的事务。
  • 场景:这是最常用的设置,适用于大多数情况。它能保证多个操作在同一个事务中执行(例如,下单操作和扣库存操作)。
  • 比喻:坐地铁。如果你已经有票(已有事务),就直接进站;如果没票(没有事务),就买一张新票(新事务)。

2. Propagation.SUPPORTS

  • 含义:如果当前存在一个事务,则加入这个事务;如果当前没有事务,则以非事务的方式继续运行。
  • 场景:适用于那些“可有可无”的非核心操作,比如查询。它可以适应调用方的事务环境,但不强求。
  • 比喻:跟团游。如果团队有行程(已有事务),你就跟着走;如果团队是自由活动(没有事务),你就自己玩(非事务)。

3. Propagation.MANDATORY (强制)

  • 含义:必须在一个已有的事务中运行。如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
  • 场景:用于强制要求必须在事务上下文中被调用的方法,否则就视为编程错误。
  • 比喻:你必须用公司的商务卡(事务)来报销,如果你试图用自己的个人卡(无事务)报销,财务会拒绝并报错。

4. Propagation.REQUIRES_NEW (新建)

  • 含义无论当前是否存在事务,都会创建一个新的事务。如果当前有事务,则把当前事务挂起。
  • 场景:用于需要独立提交或回滚的场景,不希望受外部事务失败的影响。例如日志记录,无论主业务是否成功,日志都必须被记录到数据库。
  • 比喻:无论你现在是不是在跟团游(外部事务),你都要自己单独去办一件急事(新事务),办完后你再回来继续跟团。

5. Propagation.NOT_SUPPORTED (不支持)

  • 含义:以非事务方式执行操作。如果当前存在事务,则把当前事务挂起,等该方法执行完毕后再恢复。
  • 场景:用于完全不需要事务支持的操作,比如执行某些不需要事务的数据库查询或操作。
  • 比喻:你在跟团游(外部事务)过程中,突然需要去路边一个不收门票(无事务)的公共喷泉玩一会。导游(事务管理器)会等你玩完再继续行程。

6. Propagation.NEVER (从不)

  • 含义:必须在非事务环境下执行。如果当前存在事务,则抛出异常
  • 场景:用于强制要求不能在事务中被调用的方法。
  • 比喻:某个活动明确禁止旅行团参加(禁止事务),只接受散客(非事务)。如果旅行团来了,就会被拒之门外(抛异常)。

7. Propagation.NESTED (嵌套)

  • 含义:如果当前存在事务,则在当前事务的一个嵌套事务中执行。如果当前没有事务,其行为与 REQUIRED 类似,会创建一个新事务。
    • 嵌套事务的特点:它是外部事务的一个子事务。它的提交会随外部事务一起提交,但它的回滚可以独立于外部事务(外部事务可以选择是回滚到嵌套事务前的保存点,还是回滚整个事务)。
  • 场景:适用于事务中可以独立回滚的子流程。例如,用户下单时,可以先预留库存(嵌套事务),如果后续添加优惠券失败,可以只回滚添加优惠券的操作,而保留预留的库存(或者也可以选择全部回滚)。
  • 注意:此传播行为需要 JDBC 3.0 以上驱动和数据库的支持(如 PostgreSQL),但有些资源管理器(如 JTA)可能不支持嵌套事务。
  • 比喻:玩游戏时存档(设置保存点)。你可以尽情尝试一个高风险的任务(嵌套事务),如果失败了,你可以读档回到存档点(回滚嵌套事务),而不需要从头开始玩(回滚整个事务)。

总结与选择建议

传播行为含义外部事务存在外部事务不存在
REQUIRED (默认)支持当前事务,不存在则新建加入新建
SUPPORTS支持当前事务,不存在则以非事务运行加入非事务
MANDATORY强制必须在事务中运行加入抛异常
REQUIRES_NEW挂起当前事务,创建新事务新建(挂起外部)新建
NOT_SUPPORTED以非事务运行,挂起当前事务非事务(挂起外部)非事务
NEVER必须在非事务中运行抛异常非事务
NESTED在嵌套事务中运行嵌套新建

如何选择?

  • 绝大多数情况:使用默认的 REQUIRED 即可。
  • 需要独立事务(如日志记录):使用 REQUIRES_NEW
  • 需要精细控制部分回滚:在支持的情况下,考虑使用 NESTED
  • 强制/禁止事务环境:使用 MANDATORYNEVER

文章转载自:

http://QcpiMmP8.yLyxm.cn
http://rPlU7ZCe.yLyxm.cn
http://ziaPk1Xr.yLyxm.cn
http://M7hOY021.yLyxm.cn
http://cPK3hYaz.yLyxm.cn
http://niK64oS8.yLyxm.cn
http://Wrlr6mKy.yLyxm.cn
http://mIaxtHPy.yLyxm.cn
http://iBJ0XzMB.yLyxm.cn
http://PZwb3i8P.yLyxm.cn
http://aw6ELcDw.yLyxm.cn
http://T1sINzp9.yLyxm.cn
http://G2wg1xJx.yLyxm.cn
http://RoahcGTl.yLyxm.cn
http://vNQzP9Pg.yLyxm.cn
http://V8RZCEt9.yLyxm.cn
http://RCt4UsKS.yLyxm.cn
http://Fj5GLSar.yLyxm.cn
http://N46Rb6Hn.yLyxm.cn
http://2d0L6mq8.yLyxm.cn
http://I9TZIAdI.yLyxm.cn
http://mwLGej3k.yLyxm.cn
http://R7AO3PV2.yLyxm.cn
http://jLaq3ljj.yLyxm.cn
http://Ij4TRNWX.yLyxm.cn
http://RW0Todyq.yLyxm.cn
http://DVfukXCV.yLyxm.cn
http://cc28MUto.yLyxm.cn
http://uKsfugI4.yLyxm.cn
http://sTslTjtt.yLyxm.cn
http://www.dtcms.com/a/383958.html

相关文章:

  • OpenCV一些进阶操作
  • Layer、LayUI
  • 机器视觉光源的尺寸该如何选型的方法
  • MySQL 高阶查询语句详解:排序、分组、子查询与视图
  • Mathtype公式批量编号一键设置公式居中编号右对齐
  • CKS-CN 考试知识点分享(5) 安全上下文 Container Security Context
  • 简单的分数求和 区分double和float
  • Python核心技术开发指南(066)——封装
  • SFR-DeepResearch: 单智能体RL完胜复杂多智能体架构
  • 【Docker+Nginx+Ollama】前后端分离式项目部署(传统打包方式)
  • ffplay数据读取线程
  • 回溯剪枝的 “减法艺术”:化解超时危机的 “救命稻草”(二)
  • 16-21、从监督学习到深度学习的完整认知地图——机器学习核心知识体系总结
  • 二叉树的顺序存储
  • 第7课:本地服务MCP化改造
  • CF607B Zuma -提高+/省选-
  • DMA-API(map和unmap)调用流程分析(十一)
  • LeetCode 1898.可移除字符的最大数目
  • LeetCode算法日记 - Day 42: 岛屿数量、岛屿的最大面积
  • 局域网文件共享
  • llamafactory 部署教程
  • Linux链路聚合工具之ifenslave命令案例解析
  • 资金方视角下的链改2.0:拉菲资本的观察与判断
  • AIPex:AI + 自然语言驱动的浏览器自动化扩展
  • < JS事件循环系列【四】> 事件循环补充概念:从执行细节到性能优化
  • MySQL从入门到精通:基础、安装与实战管理指南
  • 解决:Ubuntu、Kylin、Rocky系统中root用户忘记密码
  • javascript文本长度检测与自动截取,用于标题长度检测
  • 解锁 DALL・E 3:文生图多模态大模型的无限可能
  • 深入理解 LVS-DR 模式与 Keepalived 高可用集群