1 Spring事务传播行为类型
序号 | 事务传播行为类型 | 说明 |
---|---|---|
1 | PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。默认Spring事务传播行为。 |
2 | PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
3 | PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
4 | PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
5 | PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
6 | PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
7 | PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。 |
2 传播行为实践
CarOrderSelfSubmitServices 提交订单
@Service
public class CarOrderSelfSubmitServices implements CarOrderSubmitServices {
@Autowired
private CarOrderDao carOrderDao;
@Override
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = {Exception.class,RuntimeException.class})
public Integer submit(CarOrderSubmitReqDto reqDto) {
CarOrderEntity carOrderEntity = new CarOrderEntity();
carOrderEntity.setOrderNo(reqDto.getOrderNo());
carOrderEntity.setCarNo(reqDto.getCarNo());
carOrderDao.add(carOrderEntity);
Integer id = carOrderEntity.getId();
this.updateStock(id, 1);
return id;
}
@Override
public void updateStock(Integer id, Integer stockCount) {
carOrderDao.updateStockById(id,stockCount);
}
}
CarOrderDao 更新库存数量
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED,rollbackFor = {Exception.class,RuntimeException.class})
public boolean updateStockById(Integer id, Integer stockCount) {
CarOrderEntity carOrderEntity = new CarOrderEntity();
carOrderEntity.setStockCount(stockCount);
LambdaQueryWrapper<CarOrderEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CarOrderEntity::getId, id);
return super.baseMapper.update(carOrderEntity, wrapper) > 0;
}
2.1 REQUIRED
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.REQUIRED
结论:在同1个事务内一起提交
原因:因为submit已经存在事务,所以使用同1个事务
2.2 NOT_SUPPORTED
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.NOT_SUPPORTED
结论:不在同1个事务内,updateStockById更新时会死锁,等待submit提交,造成相互等待
原因:NOT_SUPPORTED模式以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
2.3 REQUIRES_NEW
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.REQUIRES_NEW
结论:不在同1个事务内,updateStockById更新时会死锁,等待submit提交,造成相互等待
原因:REQUIRES_NEW模式新建事务,如果当前存在事务,把当前事务挂起
2.4 SUPPORTS
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.SUPPORTS
结论:在同1个事务内一起提交
原因:SUPPORTS模式支持当前事务,如果当前没有事务,就以非事务方式执行。
2.5 MANDATORY
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.MANDATORY
结论:在同1个事务内一起提交
原因:MANDATORY模式使用当前的事务,如果当前没有事务,就抛出异常。
2.6 NEVER
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.NEVER
结论:不能在同1个事务内一起提交
原因:NEVER模式以非事务方式执行,如果当前存在事务,则抛出异常。
2.7 NESTED
submit方法: 事务传播行为 Propagation.REQUIRED
updateStockById方法: 事务传播行为 Propagation.NESTED
结论:在同1个事务内一起提交
原因:NESTED模式如果当前存在事务,则在嵌套事务内执行。