记一次@Transactional+@Async造成的事务不回滚问题

最近改造前两年的一个项目,一个版本发布的功能,需要操作3-4张表,使用的mybatis-plus做的持久化。

原有逻辑:

后台接收到publish请求,接入service1实现层。

service1方法添加了@Transactional执行方法:

1、add版本记录方法,默认发布版本状态为执行中

2、修改最新版本时间方法

3、service2的数据备份,由于该操作涉及三张表且数据量大比较耗时,所以在此方法上添加了@Async注解异步执行

service2数据备份方法中执行方法:

1、备份表1

2、备份表2

3、备份表3

4、修改版本发布状态为成功或失败

结果发现备份表3的操作发生异常前面操作均为回滚;

试着在service2的数据备份异步方法再加上@Transactional能保证几个备份表的操作和修改状态的操作在同一个事务下执行,但是还是不能和service1的方法同一个事务,因为主线程和子线程的在事务上是相互隔离的,子线程的异常不会影响主线程的事务混滚与否(让若主线程不主动throw出异常,子线程即使抛出了异常也不会影响主线程的);而且希望service2的方法中的第四步修改发布状态的操作不论前三步是否执行成功都执行,所以上面这样处理肯定不行。

优化方案:

把service1的发布方法改为异步执行加上@Async去掉@Transactional,其中调用service2的备份方法上去掉@Async加上@Transactional保证前三步备份步骤发生异常一起回滚,第四步修改发布状态独立出来提供一个方法加上@Transactional并且指定

propagation = Propagation.REQUIRES_NEW
1.标志REQUIRES_NEW会新开启事务,外层事务不会影响内部事务的提交/回滚
2.标志REQUIRES_NEW的内部事务的异常,会影响外部事务的回滚

这样就达到了想要的目的:不管备份是否成功,发布状态都会更新。

关机底薪到手

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值