常见的使用数据库事务的方式,即 Spring 声明式事务,使用上可能遇到的三类坑,包括:
第一,因为配置不正确,导致方法上的事务没生效。我们务必确认调用 @Transactional 注
解标记的方法是 public 的,并且是通过 Spring 注入的 Bean 进行调用的。
第二,因为异常处理不正确,导致事务虽然生效但出现异常时没回滚。Spring 默认只会对
标记 @Transactional 注解的方法出现了 RuntimeException 和 Error 的时候回滚,如果
我们的方法捕获了异常,那么需要通过手动编码处理事务回滚。如果希望 Spring 针对其他
异常也可以回滚,那么可以相应配置 @Transactional 注解的 rollbackFor 和
noRollbackFor 属性来覆盖其默认设置。
第三,如果方法涉及多次数据库操作,并希望将它们作为独立的事务进行提交或回滚,那么
我们需要考虑进一步细化配置事务传播方式,也就是 @Transactional 注解的Propagation 属性。
可见,正确配置事务可以提高业务项目的健壮性。但又因为健壮性问题往往体现在异常情
况或一些细节处理上,很难在主流程的运行和测试中发现,导致业务代码的事务处理逻辑往
往容易被忽略,因此我在代码审查环节一直很关注事务是否正确处理。
如果你无法确认事务是否真正生效,是否按照预期的逻辑进行,可以尝试打开 Spring 的部
分 Debug 日志,通过事务的运作细节来验证。也建议你在单元测试时尽量覆盖多的异常场景,这样在重构时,也能及时发现因为方法的调用方式、异常处理逻辑的调整,导致的事务失效问题。