在Spring中,事务失效是常见问题,通常与底层机制或配置错误有关。以下是常见场景及解决方法:
1. 非public方法使用@Transactional
- 原因:Spring的AOP代理默认只能拦截
public
方法。
@Transactional
private void updateData() { /* ... */ } // 事务失效!
- 解决:将方法改为
public
,或调整AOP配置(如使用AspectJ)。
2. 自调用(Self-Invocation)
public void methodA() {methodB(); // 直接调用,事务失效!
}@Transactional
public void methodB() { /* ... */ }
- 通过代理对象调用:
AopContext.currentProxy().methodB()
。
3. 异常未抛出或未被识别
- 抛出非
RuntimeException
/Error
,未配置rollbackFor
。
@Transactional
public void update() {try {// 可能抛出IOException} catch (Exception e) {// 未抛出,事务不回滚!}
}
- 在catch块中抛出
RuntimeException
或配置@Transactional(rollbackFor = Exception.class)
。
4. 传播行为配置不当
- 方法传播行为设为
Propagation.NOT_SUPPORTED
(无事务执行)。
- 解决:根据业务需求调整传播行为(如
REQUIRED
、REQUIRES_NEW
)。
5. 数据库引擎不支持事务
6. 未启用事务管理
- 场景:忘记在配置类添加
@EnableTransactionManagement
。
7. 多数据源未指定事务管理器
@Transactional("customTxManager") // 需指定事务管理器
public void multiDataSourceOp() { /* ... */ }
- 解决:在
@Transactional
中指定对应的事务管理器名称。
8. 事务方法被final/static修饰
- 原因:Spring无法代理final/static方法。
@Transactional
public final void finalMethod() { /* ... */ } // 事务失效!
9. 类未被Spring管理
- 场景:未添加
@Service
、@Component
等注解。
10. 编程式事务未提交
- 场景:使用
TransactionTemplate
但未执行操作。
transactionTemplate.execute(status -> {// 漏写业务逻辑,事务未提交!return null;
});
排查建议
- 检查日志:确认事务管理器是否启动,SQL是否在事务中执行。
- 使用调试工具:如
@Transactional
的readOnly
属性验证事务是否生效。
- 简化场景:逐步排除配置、代码、环境问题。
通过以上场景逐一排查,可快速定位事务失效原因。