下面把 传播行为 拆成“有父事务时怎么做”和“无父事务时怎么做”两个维度,比原来的「是否必须有父事务 / 是否会新建事务」更直观——一眼就能看出它在两种场景下的动作差异。
传播行为 | 父事务已存在时 | 父事务不存在时 | 典型用途 / 说明 |
---|---|---|---|
REQUIRED (默认) |
加入父事务→ 共提交 / 回滚 | 创建新事务 | 日常业务写操作,保持一致性 |
REQUIRES_NEW |
挂起父事务→ 自己新建事务 | 自己新建事务 | 写日志、发送 MQ 等:外层失败也要单独成功 |
SUPPORTS |
加入父事务 | 非事务方式执行 | 只读查询:有事务跟随一致性,没有就轻量查询 |
NOT_SUPPORTED |
挂起父事务→ 非事务方式执行 | 非事务方式执行 | 大批量/耗时操作,避免长事务锁表 |
MANDATORY |
加入父事务 | 立即抛异常 | 防御性编程:强制要求调用方已开启事务 |
NEVER |
立即抛异常 | 非事务方式执行 | 禁止在事务里跑的代码(如特殊 DDL) |
NESTED |
同一物理事务,打 SAVEPOINT→ 子回滚只回到保存点 | 创建新事务(与 REQUIRED 效果相同) |
分段回滚;需 DB / JDBC 支持保存点 |
使用 Tips
- 不想被外层事务拖垮 ➜
REQUIRES_NEW
- 可有可无事务的读操作 ➜
SUPPORTS
- 耗时任务要彻底裸跑 ➜
NOT_SUPPORTED
- 局部失败但整体继续 ➜
NESTED
(保存点) - 强约束外层必须有事务 ➜
MANDATORY
- 坚决拒绝在事务里执行 ➜
NEVER
这样,你只需关心:
「现在有没有父事务?✚ → 该传播行为会怎么做?」
就能快速判断是否满足你的业务需求。