Spring异步Async和事务Transactional注解

Spring开发中我们我们常常用到@Transaction和@Async,但这2个注解加在一起很多的开发者不敢用,担心事务不生效。下面我们就仔细讲解一下这2个注解同时运用,文章用3个场景讲述它们之间的运用,相信看完本篇文章你就能灵活运用这2个注解了。

场景一:@Async + @Transaction放在一个方法中,并且方法有异常发生

e6a9165d733c46fb9308f44b3b83d197.png

进行单元测试如下:

0230d4459fab4ce2b3088b72139829e6.png

运行结果:事务回滚了,user没有新增进入数据库。

场景二:一个同步的方法,调用异步的方法,同步的方法抛出异常。

1f4b3212430c4bc0932a908b2c0eba32.png

然后同样运行上面的单测。PS至于上面为什么用applicationContext获取Bean不在本次讲解的范畴,是属于事务是否生效的知识点,如果想知道为什么后续文章进行讲解,可以点一下关注。

结果:第一个方法数据回滚了,第二个异步的数据保存成功了。

场景三:一个同步方法,调用2个异步的方法,2个异步的方法都抛出异常。

 

同样运行上面的单测。

结论:第一个同步方法保存数据成功,第二个和第三个异步方法保存数据失败。

上面的三个场景大概,概括了我们开发中的使用的场景,由上面的场景也可以得出结论:不同线程之间的事务完全隔离,异步线程内完全可以调用异步线程。

然后我们讲解一下第一种场景为什么事务加异步的方法能生效,大部分的开发者都对此有疑问。因为事务生效只在同一个线程中才能生效而使用异步方法时Sping又新创建了一个线程,以为这个事务不生效的,其实是生效的。我们知道不管是异步还是事务都是Spring运用了它的特性Aop。Aop中切面有一个执行顺序的注解,如下是Spring事务的默认的order

int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

57572b820e89417590f551b6117e6dca.png

spring事务切面order为最大的整数值,也就是说它的执行优先级是最低的。所以可以知道Async异步的切面先执行,事务的切面后执行,通俗理解异步包裹了事务的执行,所以可以说事务是在异步的那个线程里面执行的,所以也就理解了为什么事务会生效。

8948639cd57f4d94b0a8765c01f1d173.png

 欢迎关注微信公众号:程序员xiaozhang 。如果开发中遇到Spring问题也可以微信公众号私信我,尽量帮忙查看解决。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Spring框架中,使用@Async注解可以将一个方法标记为异步执行,该方法会在一个新的线程中执行。而@Transactional注解用于开启事务,用于保证数据的一致性。 当一个被@Async注解的方法调用一个被@Transactional注解的方法时,会出现事务失效的情况。这是因为@Transactional注解只能在当前线程中开启事务,而异步方法是在新的线程中执行的,与当前线程不在同一个线程中,因此无法获取当前线程中的事务上下文。 为了解决这个问题,可以使用Spring提供的异步事务处理机制。具体来说,可以在@Async注解的方法上添加@Transaction注解,并设置propagation属性为REQUIRES_NEW,表示开启一个新的事务。这样,在异步方法中执行的数据库操作就可以在新的事务中进行,不会影响到当前线程中的事务。 举个例子: ``` @Service public class UserService { @Autowired private UserRepository userRepository; @Async @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateUser(User user) { userRepository.save(user); } } ``` 在上述例子中,updateUser方法使用了@Async和@Transactional注解,@Async注解表示该方法是异步执行的,@Transactional注解中设置propagation属性为REQUIRES_NEW,表示开启一个新的事务。 总之,为了避免@Async修饰的方法@Transactional事务失效,需要在异步方法中使用@Transaction注解开启一个新的事务

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值