「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」
事务的传播行为:用来描述某个事务传播行为修饰的方法,在嵌套进另一个方法时事务是如何传播的。
7种事务传播行为
Spring
在 org.springframework.transaction.TransactionDefinition
接口中规定了7种类型的事务传播行为。
事务传播行为 | 说明 |
---|---|
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务;如果当前存在事务,则加入到这个事务中。 (默认行为) |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,则以非事务的方式执行 |
PROPAGATION_MANDATORY | 支持当前事务,如果当前没有事务,则抛出异常 |
PROPAGATION_REQUIRES_NEW | 创建新事务,如果当前存在事务,则把当前事务挂起 |
PROPAGATION_NOT_SUPPORTED | 以非事务的方式执行,如果当前存在事务,则把当前事务挂起 |
PROPAGATION_NEVER | 以非事务的方式执行,如果当前存在事务,则抛出异常 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务中执行,如果当前没有事务,则执行PROPAGATION_REQUIRED类似的操作 |
PROPAGATION_REQUIRED
在外层方法开启 PROPAGATION_REQUIRED
事务传播机制时,内层方法不开启也能加入到事务管理中。(在同一个 bean
中和不同 bean
中的效果都是相同的)
伪代码:
/**
* 添加用户
*/
@Override
public void addUser() {
userDao.insertUser(new User("测试2",2,"男"));
userDao.insertUser(new User("测试3",3,"男"));
if (true){
throw new RuntimeException("测试异常");
}
}
/**
* 添加商品
*/
@Override
public void addShop() {
shopDao.insert(new Shop("测试商品1",new BigDecimal(1)));
// shopDao.insert(new Shop("测试商品2",new BigDecimal(2)));
}
/**
* 测试 默认事务传播
*/
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
@Override
public void test1() {
this.addUser();
this.addShop();
}
PROPAGATION_SUPPORTS
如果当前存在事务的话,就加入到当前事务中,如果不存在的话就以非事务方式执行。不管内外层方法是否在同一个 bean
中
PROPAGATION_REQUIRES_NEW
外层方法开不开启事务都可以,外层方法异常不影响内层事务提交,内层方法各自开启事务,在内层方法遇到异常时各自回滚。
伪代码:
A类
/**
* 添加商品
*/
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
@Override
public void addShop() {
shopDao.insert(new Shop("测试商品1",new BigDecimal(1)));
}
C类
/**
* 添加用户
*/
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
@Override
public void addUser() {
userDao.insertUser(new User("测试2",2,"男"));
userDao.insertUser(new User("测试3",3,"男"));
throw new RuntimeException("测试异常");
}
B类(业务调用)
@Autowired
private AService aService;
@Autowired
private CService cService;
/**
* 测试
*/
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
@Override
public void test1() {
aService.addShop();
cService.addUser();
throw new RuntimeException("外层异常");
}
PROPAGATION_NOT_SUPPORTED
使用该事务传播行为的方法,如果是在内层方法中使用,需要注意的是内层方法需要与外层方法处于不同的 bean
中,否则该事务传播行为将失效。
PROPAGATION_NEVER
以非事务的方式执行,如果当前存在事务,则抛出异常。内外层方法在同一个 bean
中时无效。