抛出异常时@Transactional注解不生效问题咨询(附代码示例)
排查Spring Boot中@Transactional抛出异常不生效的问题
嘿,我来帮你揪出这个事务不生效的问题!看了你的代码,最核心的问题已经很明显了,另外也给你列几个常见的排查方向,帮你彻底解决:
1. 最可能的原因:异常被捕获后未重新抛出
你的saveKot方法里用try-catch把Exception给捕获了,但没有在catch块里把异常重新抛出来。Spring的事务机制是靠感知方法抛出的未被捕获的异常来触发回滚的——如果异常被你自己“吞”掉了,事务管理器根本不知道发生了异常,自然不会执行回滚操作。
修复方法很简单,在catch块里重新抛出异常就行:
@Transactional(rollbackFor = Exception.class) public BaseDTO saveKot(BillDTO billDto) { try { // 业务逻辑 billRepo.save(); } catch (Exception e) { // 这里保留你的业务处理逻辑(比如日志记录等) throw e; // 重新抛出异常,让事务管理器感知到 // 或者包装成自定义异常抛出:throw new BusinessException("保存失败", e); } }
2. 检查异常类型是否匹配rollbackFor配置
你已经设置了rollbackFor = Exception.class,这个配置是对的(默认Spring只对RuntimeException和Error回滚,设置这个可以让所有Exception子类都触发回滚)。但要注意:如果你的catch块里捕获的异常被你转换成了其他类型,或者没有真正抛出符合条件的异常,也会导致回滚失效。
3. 确认Spring代理是否正常生效
虽然你已经加了@EnableTransactionManagement(proxyTargetClass=true),但还要注意:
OrderService必须是被Spring容器管理的Bean(你加了@Service,这一点没问题)- 调用
saveKot方法的必须是外部类,不能是OrderService自身的内部方法调用(比如同一个类里的A方法调用saveKot,会绕过代理,事务不生效)
4. 检查数据库是否支持事务
如果你的数据库是MySQL,要确认使用的是InnoDB引擎(MyISAM不支持事务);如果是其他数据库,也要确保对应的存储引擎支持事务特性——数据库本身不支持的话,Spring事务肯定没法生效。
先试试第一个修复方案,应该能解决大部分问题,如果还是不行,再逐一排查后面的几个点~
内容的提问来源于stack exchange,提问作者basil_benny




