spring事务失效排查

spring事务失效排查

完成线下备货成功后需要更改订单状态,涉及中订单状态的更改以及和中订单相关联的小订单状态的更改,两种订单状态的更改必须是要同时成功和失败的,一种失败后另一种成功了也需要回滚。这就需要使用到事务了。
最开始的代码实现逻辑如下:
在这里插入图片描述
运行测试后发现日志打印未启动事务
在这里插入图片描述
通过查找,猜测原因是:spring采用动态代理机制来实现事务控制,而动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!如下图(图片来源:https://www.iteye.com/topic/1122740),inBatchFinishBuy是普通方法不会执行事务切面,直接从4处开始执行,并在4处直接调用batchFinishBuy方法,导致了事务失效。

在这里插入图片描述

给inBatchFinishBuy方法加上@Transactional,重启再试,OK,日志终于出现事务启动了
在这里插入图片描述
在订单更新方法中插入一条异常,继续测试

发现中订单表更新没有回滚,最终结果是中订单更新了而小订单未更新,事务启动了但是未生效。这肯定是不允许的,继续查找原因。
直接调用updateOrder方法发现事务是生效的,中订单的更新被回滚了,问题肯定出在调用链上,根据博客:https://www.iteye.com/topic/1122740 的提示,最终分析出了原因:调用inBatchFinishBuy时发现是事务方法,会使用动态代理先执行事务切面后再执行原始对象的inBatchFinishBuy,而在inBatchFinishBuy中调用batchFinishBuy不会再走一次事务切面,直接调用本对象的batchFinishBuy,同理updateOrder方法也不会重走事务切面。所以inBatchFinishBuy、batchFinishBuy和updateOrder的事务定义是一样的,使用的是同一事务,而在batchFinishBuy方法中对异常做了catch处理,最终导致事务回滚失效。
最终解决办法如下:
在这里插入图片描述
更多方法见博客:https://www.iteye.com/topic/1122740
都是同一个思路:只要通过AOP代理调用batchFinishBuy和updateOrder方法即可走事务切面,事务增强

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值