跳到文章内容
技术手记

xz 的技术手记

把问题想清楚,
把过程记下来。

关于代码、实践,以及一点一滴的理解。

开始阅读

SpringBoot-事物-传播行为

Spring 有 7 种事务传播行为,描述的是:调用一个事务方法时,如何处理当前已有的事务。以下默认通过 Spring 代理调用、使用同一个事务管理器。

传播行为 当前没有事务 当前已有事务 记法
REQUIRED(默认) 新建事务 加入原事务 有就加入,没有就建
REQUIRES_NEW 新建事务 挂起原事务,另建事务 总是独立新建
NESTED 新建事务 在原事务内建立保存点 内层可退回保存点
SUPPORTS 无事务执行 加入原事务 随外层
NOT_SUPPORTED 无事务执行 挂起原事务,无事务执行 不用事务
MANDATORY 报错 加入原事务 必须已有
NEVER 无事务执行 报错 禁止已有

常见组合与选择。共 10 种组合。默认 A 通过代理调用另一个 Bean 的 B,使用同一个事务管理器、同一线程;NESTED 需要底层支持。

A → B 实际效果 使用场景
REQUIRED → REQUIRED 共用一个事务,一起提交或回滚。B 的异常经过事务拦截器并将事务标记为只能回滚后,A 即使 catch 也无法正常提交 创建订单+扣库存,需要一起成败
REQUIRED → REQUIRES_NEW 挂起 A 的事务,B 独立开启事务。B 已提交的修改不受 A 回滚影响;B 异常外抛仍可能触发 A 回滚 业务处理+需要独立保留的操作日志
REQUIRED → NESTED 同一个物理事务,B 建立保存点。B 可局部回滚,A 处理异常后可继续;A 最终回滚,B 也回滚 保存主记录+允许失败的可选附加信息
A 无事务 → REQUIRED B 自己开启事务,范围只覆盖 B;A 后续失败不能撤销 B 已提交的修改 无事务的入口调用一个需要保证原子性的业务操作
REQUIRES_NEW → REQUIRED B 加入 A 的事务,二者共用一个事务 A 独立执行业务补偿,B 的修改与 A 一起成败
REQUIRES_NEW → REQUIRES_NEW 挂起 A 的事务,B 再开启独立事务;B 结束后恢复 A A 执行业务补偿,B 独立保存日志
REQUIRED → NOT_SUPPORTED 挂起 A 的事务,B 无事务执行;A 回滚不能撤销 B 已提交的修改 B 查询不要求与 A 保持同一事务视图的辅助信息
REQUIRED → NEVER 当前有事务,调用 B 时直接报错,B 方法体不执行 B 明确禁止在事务中调用,检查调用方式是否合规
A 无事务 → MANDATORY 当前没有事务,调用 B 时直接报错,B 方法体不执行 扣款方法必须参与上层转账事务,禁止单独调用
SUPPORTS → REQUIRED A 无事务则 B 新建;A 已加入上游事务则 B 也加入 A 可以有事务或无事务执行,但 B 的修改必须有事务

不用背组合,记住每种行为,再逐层判断。

行为 怎么记 什么时候选
REQUIRED 有就加入,没有就建 默认选择,多个操作需要一起成败
REQUIRES_NEW 总是另开一个 需要独立提交,例如保留失败操作的日志
NESTED 同一事务,设置存档点 内层允许失败,外层处理异常后继续
SUPPORTS 随外层 有事务就参与,没有也能执行
NOT_SUPPORTED 暂停事务再执行 明确要求当前方法不参与事务
MANDATORY 没事务不准进 必须由上层事务统一管理,例如转账中的扣款
NEVER 有事务不准进 明确禁止在事务中调用

重点区分前三个,用“订单+附加信息”记:

  • REQUIRED:绑在一起,失败一起回滚。
  • REQUIRES_NEW:各自结账,B 已提交,A 回滚也撤不掉。
  • NESTED:中途存档,B 可以退回存档点;A 最终回滚,仍然全部撤销。

看组合时,只问一句:

走到 B 时有没有事务?B 要加入、另开,还是拒绝它?

实际开发优先用 REQUIRED,有明确的独立提交或局部回滚需求,再考虑另外两种。

posted @ 2026-11-07 17:12  xz_move_on  阅读(5)  评论(0)    收藏  举报