27 lines
2.4 KiB
Markdown
Raw Normal View History

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