5、Spring 全家桶:为什么 @Transactional 是一只看不见的老虎?

67 阅读1分钟

今天我们不聊 Spring Boot 启动慢、不聊 Spring Cloud 复杂,只聊一个大家用得最多却理解最少的注解:

@Transactional

这东西看似一句注解,实际上藏着一只看不见的老虎


1️⃣ @Transactional 的工作机制

✅ 它依赖 Spring AOP,基于代理实现事务管理
✅ 默认用的是 代理对象(JDK 动态代理 or CGLIB 动态代理)
✅ 它不是魔法,而是围绕你的方法包了一层 try-catch-finally,决定什么时候提交、回滚


2️⃣ 常见坑:你掉过几个?

同类方法调用无效

// A 类
@Transactional
public void methodA() {
    methodB();
}

@Transactional
public void methodB() {
    // ...
}

因为内部调用不会经过代理 → methodB 的事务失效。


异常未抛出事务不回滚
默认只对 RuntimeException 和 Error 回滚,其他异常要配置 rollbackFor


多线程事务失效
事务绑定在当前线程上,异步线程要单独处理事务。


3️⃣ 如何正确用 @Transactional?

✅ 事务方法尽量放到独立的 Service 层
✅ 切记:用接口代理时,必须是 public 方法
✅ 对非 RuntimeException 的情况,加上 rollbackFor = Exception.class
✅ 异步线程要单独声明事务,比如 @Async + @Transactional 不叠加生效

image.png

4️⃣ 小幽默:老板的钱飞了

有次项目上线,财务系统用 @Transactional 管理转账操作,结果转账失败后没抛出 RuntimeException,钱转出去还不回滚。
老板怒了:
“谁说 Spring 很稳的?我的钱呢?”
我:……(赶紧补 rollbackFor)


5️⃣ 总结

✅ @Transactional 依赖代理和 AOP
✅ 同类调用、异常类型、线程模型,都会影响事务生效
✅ 事务是保证数据一致性的底线,一旦用错,可能直接炸生产