背景
@Transactional注解大家在开发中应该经常用到,把他放在方法上或者类上用来作事务控制的。里面有个propagation属性可能大家平时没怎么关注。今天就给大家介绍一个@Transactional注解的propagation属性的作用。
理论
- @Transactional注解propagation属性有这些值
- 具体含义
实践
- propagation注解默认值REQUIRED,两个事务会合并成一个事务,要么同时成功要么同时回滚。这个简单不用过多解释。这里主要讲解一下REQUIRES_NEW和NESTED。
- 场景:A调用B
- REQUIRES_NEW
根据理论介绍,无论A是否有事务,B都会新建一个事务。两个事务互不影响,A事务回滚不会影响B事务。
虽然理论是这样,但我这里要着重解释的是,AB事务互不影响,A事务回滚不会影响B事务,但是B事务回滚,A也要回滚。
1)A有事务,B中抛出异常,A和B一起回滚:
UserService中的方法testRequiredNew1
调用GoodsService中的testRequiredNew1
执行结果
user表和goods表都没有插入成功
2) A有事务,A中抛出异常,A回滚,B不回滚
UserService中的方法testRequiredNew2
调用GoodsService中的testRequiredNew2
执行结果
user表插入失败和goods表插入成功
- NESTED
根据理论介绍,无论A是否有事务,B都会新建一个事务,如果A有事务,B事务是A的子事务。A回滚B也会回滚,B回滚则不会影响到A
1)A有事务,B中抛出异常,B回滚,A不回滚:
UserService中的方法testNested1(为啥这里一定还需要try catch住调用goodsService的方法呢,不是NESTED本身就是B回滚不会影响到A吗,子事务回滚不影响父事务,如果不try catch,A也回滚了,有知道的小伙伴可以留言)
调用GoodsService中的testNested1
执行结果
user表插入数据成功,goods表插入失败
2)A有事务,A中抛出异常,A回滚,B也回滚:
UserService中的方法testNested2
调用GoodsService中的testNested2
执行结果
user表和goods表都插入失败
总结
- REQUIRES一起回滚
- REQUIRES_NEW,A不会影响到B,B会影响到A
- NESTED,A会影响到B,B不会影响到A(前提是try catch住调用B的方法)(与REQUIRES_NEW相反)
问题
在NESTED中,B事务抛出异常,A方法中如果不try catch住调用的B方法,A也回滚了。
为啥这里一定还需要try catch住调用goodsService的方法呢,不是NESTED本身就是B回滚不会影响到A吗,子事务回滚不影响父事务,如果不try catch,A也回滚了,有知道的小伙伴可以留言*