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

Spring 事务传播行为+实战场景+避坑指南

一、先搞懂:Spring 事务传播机制到底解决什么?

场景
ServiceA.methodA() 调用 ServiceB.methodB()
两个方法都加了@Transactional

问题:

  • 谁的事务生效?
  • 异常了谁回滚?
  • 要不要共用一个事务?

事务传播行为 = 定义 方法之间调用时,事务如何传递


二、Spring 7 大事务传播行为

Spring 定义在Propagation枚举里:

publicenumPropagation{REQUIRED,// 最常用:默认SUPPORTS,MANDATORY,REQUIRES_NEW,// 高频NOT_SUPPORTED,NEVER,NESTED;// 嵌套事务}

三大分类

  1. 支持当前事务(有就用,没有就建)
  2. 不支持当前事务(有也挂起,不用)
  3. 嵌套事务(子事务,可独立回滚)

三、7 大传播行为 图解 + 场景 + 实战

1)REQUIRED

Spring 默认,90% 业务用这个

  • 有事务 → 加入
  • 没事务 → 创建新事务
  • 同生共死,一个回滚全回滚

场景

订单创建 + 扣库存,必须一起成功/失败

调用关系

A(REQUIRED) 调用 B(REQUIRED)
同一个事务

异常结果

  • B 抛异常 → A、B 都回滚
  • A 抛异常 → A、B 都回滚

2)REQUIRES_NEW

创建新事务,当前事务挂起

  • 无论有没有事务,都新建独立事务
  • A 和 B 事务完全隔离
  • B 回滚不影响A,A回滚不影响B

场景

  • 日志记录(失败不能影响主流程)
  • 发送消息/通知
  • 子任务独立提交

调用

A(REQUIRED) 调用 B(REQUIRES_NEW)
两个独立事务

异常结果

  • B 异常回滚 → A 可以捕获,继续提交
  • A 异常回滚 → 不影响 B 已提交的数据

3)NESTED(嵌套事务)

Savepoint 机制,子事务可以独立回滚

  • 有事务 → 创建嵌套子事务
  • 没事务 → 像 REQUIRED 一样新建
  • 父事务回滚 → 子事务必回滚
  • 子事务回滚 → 父事务可以继续执行

场景

子步骤失败,不希望整个流程失败

特点

不是独立事务,依赖主事务


4)SUPPORTS

有事务就加入,没有就以非事务运行

场景

查询方法,可事务可不事务


5)MANDATORY

强制必须有事务,没有就直接抛异常

场景

强制该方法必须在事务内执行,防止误调用


6)NOT_SUPPORTED

不支持事务,当前事务挂起,以非事务运行


7)NEVER

强制非事务,存在事务就抛异常


四、最核心的 3 个

1. REQUIRED(同生共死)

2. REQUIRES_NEW(独立隔离)

3. NESTED(嵌套可回滚)


五、源码底层原理(深度解析)

Spring 事务核心类:
PlatformTransactionManager + TransactionSynchronizationManager

1. 事务挂起/恢复 源码逻辑

// 简化版源码逻辑if(传播行为==REQUIRES_NEW){// 挂起旧事务ObjectsuspendedResources=suspend(transaction);try{// 创建新事务returnstartTransaction();}finally{// 恢复旧事务resume(suspendedResources);}}

2. 事务传递本质

ThreadLocal 保存当前事务连接
TransactionSynchronizationManager.resources

3. NESTED 底层

使用 JDBCSavepoint

connection.setSavepoint();

六、实战最容易踩的 5 个坑

坑1:同类方法内调用,事务失效

@ServicepublicclassOrderService{@Transactionalpublicvoida(){b();// 同类内调用,不经过代理 → 事务失效!}@Transactional(propagation=REQUIRES_NEW)publicvoidb(){}}

解决方案

  • 自己注入自己
  • AopContext.currentProxy()

坑2:try-catch 导致事务不回滚

@Transactionalpublicvoida(){try{b();// b抛异常}catch(Exceptione){// 吞了异常 → 事务不回滚}}

坑3:REQUIRES_NEW 导致事务相互看不见

B 是新事务,A 未提交,B查不到 A 的数据


坑4:NESTED 必须支持 JDBC 3.0 Savepoint

不支持会自动降级为 REQUIRED


坑5:多线程调用,事务完全不共享

新线程 = 新事务,和主线程无关


七、实战指南:业务场景怎么选?

1)正常业务(增删改)

REQUIRED(默认)

2)日志、消息、通知、子任务

REQUIRES_NEW
失败不影响主流程

3)子步骤可回滚,主流程继续

NESTED

4)查询方法

SUPPORTS / 不加事务

5)必须在事务内运行

MANDATORY


八、一张表彻底记住

传播行为有无事务关系回滚影响
REQUIRED无则创建共用同一个一起回滚
REQUIRES_NEWalways新建独立事务互不影响
NESTED嵌套子事务父子关系子不影响父,父影响子

九、一句话终极总结

  • REQUIRED:共用事务,同生共死
  • REQUIRES_NEW:独立事务,互不干扰
  • NESTED:嵌套事务,子可回滚父不回滚
  • 同类内调用、try-catch、多线程都会导致事务失效
http://www.jsqmd.com/news/576891/

相关文章:

  • C# 读取数据库表结构工具设计与实现
  • 5分钟学会在Windows上直接安装Android应用:APK-Installer终极指南
  • AI率降完又反弹原因在这里解决方案也在 - 我要发一区
  • OpenClaw技能扩展:安装Qwen3-4B专用插件实现代码生成
  • 从零到集群:基于Rocky Linux ARM64的虚拟化平台构建与自动化部署实战
  • Diablo Edit2实用指南:如何高效管理暗黑破坏神II角色存档
  • 2026年除虫灭鼠应用白皮书小区仓储场景解析 - 优质品牌商家
  • 广州市增城添伟建材经营部:越秀区做围挡出售集装箱回收电话TOP8 - LYL仔仔
  • AI开发-python-langchain框架(--串行流程 )
  • 从“快慢”到“方向”:深度拆解导数、偏导与梯度的本质,让你彻底看懂微积分的灵魂
  • 2026铁艺大门优质厂家推荐及选购攻略 - 优质品牌商家
  • 用DeepSeek写论文AI率太高这样处理最快 - 我要发一区
  • 如何用Dism++打造高效Windows系统维护工作流
  • 提升团队效率:基于快马平台自动化生成标准化虚拟机安装教程
  • 苏州来财物资回收有限公司:姑苏区做制冷设备 中央空调回收 废金属回收电话TOP6 - LYL仔仔
  • LeetCode 删除无效的括号:python 题解
  • 2026-04-02 临床指南结构化研究
  • 2025届毕业生推荐的十大降AI率平台推荐榜单
  • 号速通科技联系方式查询:关于GEO优化服务提供商的联系途径与客观使用评估指南 - 十大品牌推荐
  • 生发机构有用吗?黑奥秘开创头发理疗品类,让生发机构更科学 - 美业信息观察
  • 告别手动查询:用快马AI生成批量处理工具,极速搞定期刊分区对比
  • 新手福音,用快马ai生成burpsuite超详细图文安装教程应用
  • 3分钟搞定微信QQ防撤回:告别“对方已撤回“的实用指南
  • 别再乱选格式了!LVGL图片转换工具(lv_img_conv)保姆级使用指南,从BMP到C数组一次搞定
  • 2026专业口腔门诊部牙齿美白评测深度解析 - 优质品牌商家
  • 聊聊库尔勒遮阳天幕价格,推荐口碑好且费用合理的供应商 - 工业品牌热点
  • 【WCH蓝牙系列芯片】-基于CH592开发板—2.4G方式接收BLE广播数据
  • 看了这篇文章,我终于弄懂机器学习到底是怎么回事了
  • OpenCascade实战:TopoDS_Shape数据结构的高效遍历与优化策略
  • 如何快速搭建个人视频播放平台:H-Player V2完整指南