循环中的事务处理

1、业务场景

通常业务开发中会遇到循环处理复杂业务数据的场景,此时需要事务支持,一般会遇到两种情况:

(1)整个循环业务功能处理需要同时成功或者同时失败回滚。

(2)循环中的每一次业务处理需要相互独立互斥,处理成功正常插入或修改数据库中的数据,失败的业务处理的数据正常回滚,单次循环处理的事务都是相互独立 互不干扰的。

2、处理方案

1、对于上面的第一种场景事务很好处理,在整个循环处理的业务方法上加上@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) 注解 默认的事务传播属性即可。

2、对于第二种的场景事务处理稍微复杂一点,首先将循环处理的业务功能单独抽出一个业务类,在其中实现业务处理方法,然后在这个方法上加上@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) ,此时事务的传播属性就换成了REQUIRES_NEW,这个事务传播属性表示新建事务,如果当前存在事务,把当前事务挂起,新建的事务将和被挂起的事务没有任何关系,是两个独立的事务。这样就能很好的解决单次循环之间的事务独立,互不干扰的问题。

3、特别注意

1、当然以上的两种场景解决方案都是基于你的事务是生效的,切记不要内部类调用带有事务的方法,否则事务会失效,因为我们知道spring的@Transactional事务生效的一个前提是进行方法调用前经过拦截器TransactionInterceptor,也就是说只有通过TransactionInterceptor拦截器的方法才会被加入到spring事务管理中,查看spring源码可以看到,AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice方法中会从调用方法中获取@Transactional注解,如果有该注解,则启用事务,否则不启用。这个方法是通过spring的AOP类CglibAopProxy的内部类DynamicAdvisedInterceptor调用的,而DynamicAdvisedInterceptor继承了MethodInterceptor,用于拦截方法调用,并从中获取调用链。如果是在同一个类中的方法调用,则不会被方法拦截器拦截到,因此事务不会起作用,必须将方法放入另一个类,并且该类通过spring注入。

2、事务中如果想加入try catch进行捕捉异常进行一些业务处理,那么切记在catch最后进行throw 异常,否则捕捉了异常不抛出,事务回滚将失效。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要成为码神的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值