一、@Transactional 为什么失效
Spring 事务基于 AOP 代理,以下情况会失效:
| 场景 | 原因 |
|---|---|
| 同类方法内部调用 | 没走代理,b() 的事务不生效 |
| 非 public 方法 | Spring 默认只对 public 代理 |
| 异常被 catch 吞掉 | 没抛到代理,不回滚 |
| 抛了受检/自定义非 RuntimeException | 默认只回滚 RuntimeException |
| 数据库引擎不支持 | 如 MyISAM 无事务 |
二、正确写法
@Service
public class OrderService {
@Transactional(rollbackFor = Exception.class) // 显式指定回滚
public void create() {
// 同类的其他事务方法需通过注入的自身代理调用
// 异常要抛出,别吞
}
}
三、传播行为
REQUIRED(默认,加入已有事务)/ REQUIRES_NEW(挂起旧事务开新)/ NESTED(嵌套保存点)。选错会导致”想独立回滚却一起回滚”或反之。
口诀:内部调用用代理、异常要抛出、rollbackFor 显式写、引擎要支持。