事务的传播机制
🌱事务传播机制总结笔记(Spring)
在 Spring 中,事务管理不仅仅是对 ACID 原则的保证,更重要的是事务传播行为(Propagation),它定义了在一个方法被另一个方法调用时,事务应该如何传播。
🌟事务传播机制概述
事务传播行为定义在 org.springframework.transaction.annotation.Propagation 枚举中,适用于 @Transactional 注解的 propagation 属性。
@Transactional(propagation = Propagation.REQUIRED)
🔁 七种事务传播行为详解
| 传播行为 | 说明 | 场景示例 |
|---|---|---|
REQUIRED ✅ |
默认行为,当前存在事务就加入,否则新建事务 | 最常用 |
REQUIRES_NEW 🔄 |
总是新建事务,如果有事务则挂起当前事务 | 日志操作、异步通知等 |
NESTED 🌿 |
如果当前事务存在,开启嵌套事务(使用保存点回滚);否则新建事务 | 同一个方法中部分回滚 |
SUPPORTS 🔍 |
如果有事务就加入,没有就非事务方式执行 | 可选事务逻辑 |
NOT_SUPPORTED 🚫 |
总是非事务方式执行,如果有事务则挂起当前事务 | 查询类接口、只读操作 |
NEVER ❗ |
必须没有事务,有事务则抛异常 | 不允许事务执行 |
MANDATORY 📌 |
必须有事务,没有事务则抛异常 | 限制只能在事务中运行的方法 |
📦行为对比图
| 行为 | 是否新建事务 | 是否加入当前事务 | 有事务时挂起 |
|---|---|---|---|
| REQUIRED | 否(默认) | 是 | 否 |
| REQUIRES_NEW | 是 | 否 | 是 |
| NESTED | 是(嵌套) | 是 | 否 |
| SUPPORTS | 否 | 是(有)/否(无) | 否 |
| NOT_SUPPORTED | 否 | 否 | 是 |
| NEVER | 否 | 否 | 抛异常 |
| MANDATORY | 否 | 是 | 无事务抛异常 |
🎯使用建议
- ✅ 推荐使用
REQUIRED,能自动适应当前事务环境。 - ⚠ 使用
REQUIRES_NEW需注意:过多会破坏整体事务一致性,适合日志或事务隔离的特殊场景。 - 🌿
NESTED适合局部容错处理,但仅在支持“保存点”的事务管理器(如 JDBC)中有效。 - ❌
NEVER和MANDATORY主要用于特定业务限制,不建议随意使用。
✍️代码示例
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder() {
// 主事务
saveOrder();
logService.recordLog(); // 假如这里用的是 REQUIRES_NEW,会挂起主事务
}
}
@Service
public class LogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void recordLog() {
// 独立事务处理日志
insertLog();
}
}
🧠小结
- 传播机制决定了事务的“嵌套行为”和“独立性”。
- 使用传播行为时应结合业务需求、异常处理和数据一致性进行权衡。
- 推荐结合
rollbackFor和@Transactional的其他属性一起使用以提高控制力。
浙公网安备 33010602011771号