1.问题场景描述
在方法中操作数据库,向表中插入一条数据;然后抛出RuntimeException,发现事务没有回滚,插入的数据依然提交到了数据库中。
2.问题查找及分析过程
2.1 首先查看项目中是否配置了事务
项目中确实做了事务相关的配置:
spring.transaction.expression=execution(* xxxxxxx.service.impl.*Impl.*(..))
那么这个配置是否生效呢?我们在执行insert后面手动抛出一个RuntimeException,看到如下的报错信息,说明异常确实抛出了,但是查询数据后发现,事务确实没有回滚。
2.2 没办法,打断点跟代码吧,看执行过程
我们根据报错的日志,找到 TransactionAspectSupport 和 TransactionInterceptor这两个类:
找到日志中报错的TransactionInterception的invok()方法,在这里打断点,
然后进入invokWithinTransaction()这个方法,就进入到了其父类TransactionAspectSupport的invokWithinTransaction()方法,我们在里面打断点继续跟踪执行过程:
然后继续,我们进入异常后回滚事务的方法:completeTransactionAfterThrowing(txInfo, var17)
跟到这里面,我们注意rollbackOn(ex)方法和txInfo.getTransactionManager().rollback()方法,
1.rollbackOn(ex)方法(在DefaultTransactionAttribute类里)的入参是一个异常类型,通过这个方法的源码我们可以发现,Spring事务默认只有在发生RuntimeException类型的异常和Error时才走下面的rollback()方法,也就是默认在捕捉到Runt