关于Spring-tx 5.2.9抛出Exception异常仍然提交的问题

问题描述:

在Service事务层,由于某些原因导致事务无法完成并抛出了Exception异常,预期DB是会执行回滚操作,但实际却是View层提示错误,DB完成提交。


原因分析:

先不管三七二十一,事务有问题 TransactionInterceptor 绝对是跑不掉的,查看代码
关于Spring-tx 5.2.9抛出Exception异常仍然提交的问题_第1张图片方法小长,不过大部分我们不关心,直捣黄龙,直接查看completeTransactionAfterThrowing 方法(PS:emmmm…,别问我怎么找到它的,这命名已经很亲切了)
关于Spring-tx 5.2.9抛出Exception异常仍然提交的问题_第2张图片
该方法的部门片段如下:
关于Spring-tx 5.2.9抛出Exception异常仍然提交的问题_第3张图片
稍微调试下,不难发现,问题出在txInfo.transactionAttribute.rollbackOn(ex) 这句上,继续深入,就不难发现,问题的源头出在了RuleBasedTransactionAttributeDefaultTransactionAttribute 这两个类上,查看RuleBasedTransactionAttribute类rollbackOn方法发现,在spring 5.2.9中有了个回滚规则的东东,如图关于Spring-tx 5.2.9抛出Exception异常仍然提交的问题_第4张图片到这里,问题的原因就很明白了,肯定是没有配置回滚规则,回头看下默认规则,也就是上述提到的DefaultTransactionAttribute的类,如图
在这里插入图片描述好吧,清晰明朗,默认只有在抛出的异常是RuntimeExceptionError异常时才执行回滚,不然事务仍然会提交的。


解决方案:

知道原因就很好办了,这里就不深究代码了,有兴趣的自己去瞄下,直接给出办法:

  1. 抛出 RuntimeException 或者 Error类型的异常,这里我推荐这种,毕竟省时省力
  2. 定义事务advice的时候指明异常名称,大概的格式如下(关联类关联类DefaultTransactionAttribute)
    关于Spring-tx 5.2.9抛出Exception异常仍然提交的问题_第5张图片
    注意:rollback-for内容格式不保证正确,这只是博主看代码脑补的。
    另外,注解部分也支持,对应的类是SpringTransactionAnnotationParser,有需要的可以自己瞄下。

最后,如果大家还有其他方式的话欢迎大家留言。


PS.古人云:“ 三人行,必有我师焉”,若你也有同样的想法,不妨关注下本人的公众号,在将来的日子里,大家一起学习进步。

你可能感兴趣的:(spring,spring)