Spring 事务传播行为:Spring 6 / Boot 3 实战边界
1. 传播行为
- REQUIRED:有事务就加入,没有就创建。
- REQUIRES_NEW:挂起外层事务,创建独立事务,会额外占用连接。
- SUPPORTS:有就加入,没有也可以无事务。
- NOT_SUPPORTED:挂起事务,以非事务方式执行。
- MANDATORY:必须已有事务。
- NEVER:已有事务则失败。
- NESTED:在支持 savepoint 的事务中建立嵌套边界。
2. 示例
@Service
public class OrderService {
@Transactional(rollbackFor = Exception.class)
public void create(Order order) {
repository.insert(order);
auditService.record(order.id());
}
}
@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void record(long id) {
// 独立提交审计事务
}
}
3. 事务不生效
声明式事务依赖代理,this.innerMethod() 可能绕过代理。其他原因包括 Bean 由 new 创建、异常被捕获、受检异常未配置 rollbackFor、调用了另一个线程、数据库不支持事务或事务管理器错误。优先拆分 Bean 让调用经过代理。
4. 系统边界
NESTED 通常依赖同一物理事务和 savepoint;REQUIRES_NEW 使用独立物理事务。Spring 本地事务不会自动跨线程、MQ、HTTP 或 RPC 传播。跨服务应使用可靠消息、补偿、TCC 或 Seata。