一、演示Spring的默认传播行为(REQUIRED)
1.1、运行之前表中的数据
1.2、StockServiceImplREQUIRED
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/10/30 15:43
* @Description: 演示REQUIRED的传播行为
* 外部不存在事务:开启新的事务
* 外部存在事务:加入到当前事务
*/
@Service(value = "stockServiceREQUIRED")
public class StockServiceImplREQUIRED extends ServiceImpl<StockMapper, StockDO> implements StockService {
@Resource
private StockMapper stockMapper;
@Resource
private IntegralService integralServiceREQUIRED;
/**
*
* REQUIRED传播行为
* @param id
* @param num
* 场景一:外部事务 & 内部事务都没有异常
* 预期结果:外部事务和内部事务都正常提交
* 实际结果:外部事务和内部事务都正常提交
* 对应方法:m1()
*
* 场景二:外部事务有异常,内部事务没有异常
* 预期结果:外部事务和内部事务都回滚
* 实际结果:外部事务和内部事务都回滚
* 对应方法:m2()
*
* 场景三:外部事务正常,内部事务有异常,但是外部事务将异常捕获并抛出了
* 预期结果:外部事务和内部事务都回滚
* 实际结果:外部事务和内部事务都回滚
* 对应方法:m3()
*
* 场景四:外部事务正常,内部事务有异常(内部事务捕获了异常,但是自己处理了),但是外部事务将异常捕获自己处理 or 将异常抛出去了
* 预期结果:外部事务和内部事务都正常提交
* 实际结果:外部事务和内部事务都正常提交
* 对应方法:m4()
*
* 场景五:外部方法不存在事务且有异常,内部方法存在事务且有异常也没有处理或者将异常抛出去了
* 预期结果:外部方法正常提交,内部方法回滚
* 实际结果:外部方法正常提交,内部方法回滚
* 对应方法:m5()
*
* 其他场景:...
*
* 总结:
* 把握一个原则,REQUIRED的传播特点是:
* 当外部方法存在事务时,被调用方法将和外部方法共用同一个事务
* 当外部方法不存在事务时,被调用方法将开启一个新事务
* 然后看异常是怎么处理的,是抛出去还是自己捕获异常进行处理
*
*/
// @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
@Override
public void reduceStock(Long id, Integer num) {
m5(id, num);
}
private void m5(Long id, Integer num) {
System.out.println("============>StockServiceImplREQUIRED的m5()执行了...");
try {
// 减库存
StockDO dbStock = stockMapper.selectById(id);
StockDO updateStock = new StockDO();
BeanUtils.copyProperties(dbStock, updateStock);
updateStock.setNum(dbStock.getNum() - num);
stockMapper.updateById(updateStock);
// 增加积分
IntegralDO updateIntegral = new IntegralDO();
updateIntegral.setPreIntegral(0);
updateIntegral.setCurrentIntegral(1000);
updateIntegral.setUserId(1L);
integralServiceREQUIRED.addIntegral(updateIntegral);
int i = 10 / 0;
} catch (Exception e) {
throw new RuntimeException(e);
// e.printStackTrace();
}
}
private void m4(Long id, Integer num) {
System.out.println("============>StockServiceImplREQUIRED的m4()执行了...");
try {
// 减库存
StockDO dbStock = stockMapper.selectById(id);
StockDO updateStock = new StockDO();
BeanUtils.copyProperties(dbStock, updateStock);
updateStock.setNum(dbStock.getNum() - num);
stockMapper.updateById(updateStock);
// 增加积分
IntegralDO updateIntegral = new IntegralDO();
updateIntegral.setPreIntegral(0);
updateIntegral.setCurrentIntegral(1000);
updateIntegral.setUserId(1L);
integralServiceREQUIRED.addIntegral(updateIntegral);
} catch (Exception e) {
throw new RuntimeException(e);
// e.printStackTrace();
}
}
private void m3(Long id, Integer num) {
System.out.println("============>StockServiceImplREQUIRED的m3()执行了...");
try {
// 减库存
StockDO dbStock = stockMapper.selectById(id);
StockDO updateStock = new StockDO();
BeanUtils.copyProperties(dbStock, updateStock);
updateStock.setNum(dbStock.getNum() - num);
stockMapper.updateById(updateStock);
// 增加积分
IntegralDO updateIntegral = new IntegralDO();
updateIntegral.setPreIntegral(0);
updateIntegral.setCurrentIntegral(1000);
updateIntegral.setUserId(1L);
integralServiceREQUIRED.addIntegral(updateIntegral);
} catch (BeansException e) {
throw new RuntimeException(e);
}
}
private void m2(Long id, Integer num) {
System.out.println("============>StockServiceImplREQUIRED的m2()执行了...");
try {
// 减库存
StockDO dbStock = stockMapper.selectById(id);
StockDO updateStock = new StockDO();
BeanUtils.copyProperties(dbStock, updateStock);
updateStock.setNum(dbStock.getNum() - num);
stockMapper.updateById(updateStock);
// 增加积分
IntegralDO updateIntegral = new IntegralDO();
updateIntegral.setPreIntegral(0);
updateIntegral.setCurrentIntegral(1000);
updateIntegral.setUserId(1L);
integralServiceREQUIRED.addIntegral(updateIntegral);
// 模拟异常
int i = 10 /0;
} catch (BeansException e) {
throw new RuntimeException(e);
}
}
private void m1(Long id, Integer num) {
System.out.println("============>StockServiceImplREQUIRED的m1()执行了...");
try {
// 减库存
StockDO dbStock = stockMapper.selectById(id);
StockDO updateStock = new StockDO();
BeanUtils.copyProperties(dbStock, updateStock);
updateStock.setNum(dbStock.getNum() - num);
stockMapper.updateById(updateStock);
// 增加积分
IntegralDO updateIntegral = new IntegralDO();
updateIntegral.setPreIntegral(0);
updateIntegral.setCurrentIntegral(1000);
updateIntegral.setUserId(1L);
integralServiceREQUIRED.addIntegral(updateIntegral);
} catch (BeansException e) {
throw new RuntimeException(e);
}
}
}
1.3、IntegralServiceImplREQUIRED
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/10/30 15:43
* @Description: 演示REQUIRED的传播行为
* 外部不存在事务:开启新的事务
* 外部存在事务:加入到当前事务
*/
@Service(value = "integralServiceREQUIRED")
public class IntegralServiceImplREQUIRED extends ServiceImpl<IntegralMapper, IntegralDO> implements IntegralService {
@Resource
private IntegralMapper integralMapper;
/**
*
* REQUIRED传播行为
* 场景一:外部事务 & 内部事务都没有异常
* 预期结果:外部事务和内部事务都正常提交
* 实际结果:外部事务和内部事务都正常提交
* 对应方法:m1()
*
* 场景二:外部事务有异常,内部事务没有异常
* 预期结果:外部事务和内部事务都回滚
* 实际结果:外部事务和内部事务都回滚
* 对应方法:m2()
*
* 场景三:外部事务正常,内部事务有异常,但是外部事务将异常捕获并抛出了
* 预期结果:外部事务和内部事务都回滚
* 实际结果:外部事务和内部事务都回滚
* 对应方法:m3()
*
* 场景四:外部事务正常,内部事务有异常(内部事务捕获了异常,但是自己处理了),但是外部事务将异常捕获自己处理 or 将异常抛出去了
* 预期结果:外部事务和内部事务都正常提交
* 实际结果:外部事务和内部事务都正常提交
* 对应方法:m4()
*
* 场景五:外部方法不存在事务且有异常,内部方法存在事务且有异常也没有处理或者将异常抛出去了
* 预期结果:外部方法正常提交,内部方法回滚
* 实际结果:外部方法正常提交,内部方法回滚
* 对应方法:m5()
*
* 其他场景:...
*
* 总结:
* 把握一个原则,REQUIRED的传播特点是:
* 当外部方法存在事务时,被调用方法将和外部方法共用同一个事务
* 当外部方法不存在事务时,被调用方法将开启一个新事务
* 然后看异常是怎么处理的,是抛出去还是自己捕获异常进行处理
*
*/
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
@Override
public void addIntegral(IntegralDO updateIntegral) {
m5(updateIntegral);
}
private void m5(IntegralDO updateIntegral) {
try {
System.out.println("============>IntegralServiceImplREQUIRED的m5()执行了...");
integralMapper.insert(updateIntegral);
// 模拟异常
int i = 10 / 0;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void m4(IntegralDO updateIntegral) {
try {
System.out.println("============>IntegralServiceImplREQUIRED的m4()执行了...");
integralMapper.insert(updateIntegral);
// 模拟异常
int i = 10 / 0;
} catch (Exception e) {
e.printStackTrace();
}
}
private void m3(IntegralDO updateIntegral) {
System.out.println("============>IntegralServiceImplREQUIRED的m3()执行了...");
integralMapper.insert(updateIntegral);
// 模拟异常
int i = 10 / 0;
}
private void m2(IntegralDO updateIntegral) {
System.out.println("============>IntegralServiceImplREQUIRED的m2()执行了...");
integralMapper.insert(updateIntegral);
}
private void m1(IntegralDO updateIntegral) {
System.out.println("============>IntegralServiceImplREQUIRED的m1()执行了...");
integralMapper.insert(updateIntegral);
}
}
1.4、测试结果
1.5、数据变化
stock表中的库存数量没有发生变化,integral(积分表)表没有增加积分。符合预期