系列四十三、Spring的事务传播行为案例演示(二)#REQUIRES_NEW

一、演示Spring的默认传播行为(REQUIRES_NEW)

1.1、StockServiceImplREQUIRES_NEW

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/30 15:43
 * @Description: 演示REQUIRES_NEW的传播行为
 *      外部不存在事务:开启新的事务
 *      外部存在事务:把当前事务挂起,开启新事务
 */
@Service(value = "stockServiceREQUIRES_NEW")
public class StockServiceImplREQUIRES_NEW extends ServiceImpl implements StockService {

    @Resource
    private StockMapper stockMapper;

    @Resource
    private IntegralService integralServiceREQUIRES_NEW;

    /**
     * REQUIRES_NEW传播行为
     * @param id
     * @param num
     * 场景一:外部事务存在异常,内部事务不存在异常,且没有处理异常
     *      预期结果:外部事务回滚,内部事务正常执行
     *      实际结果:外部事务回滚,内部事务正常执行
     *      对应方法:m1()
     *
     * 场景二:外部事务正常,内部事务有异常,但是在外部事务调用内部事务时,将内部事务的异常捕获并抛出去
     *      预期结果:外部事物和内部事务都会回滚
     *      实际结果:外部事物和内部事务都会回滚
     *      对应方法:m2()
     *      注意事项(坑):如果出现异常时,在catch代码块中将异常捕获自己处理了,没有往外抛,那么执行的结果是:外部事务提交,内部事务回滚
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    @Override
    public void reduceStock(Long id, Integer num) {
        m2(1L,10);
    }

    private void m2(Long id, Integer num) {
        System.out.println("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);
            integralServiceREQUIRES_NEW.addIntegral(updateIntegral);
        } catch (Exception e) {
            // throw new RuntimeException(e);
            e.printStackTrace();
        }
    }

    private void m1(Long id, Integer num) {
        System.out.println("m1方法执行了...");
        // 减库存
        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);
        integralServiceREQUIRES_NEW.addIntegral(updateIntegral);

        /**
         * REQUIRES_NEW传播行为案例一:外部事务方法存在异常,被调用事务方法无异常
         * 模拟异常(外部事务方法存在异常,被调用事务方法无异常)
         * stock(库存表)表中的数据回滚,integral(积分表)中插入了一条数据
         */
        int i = 10 / 0;
    }
}

1.2、IntegralServiceImplREQUIRES_NEW

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/30 15:42
 * @Description: 演示REQUIRES_NEW的传播行为
 *      外部不存在事务:开启新的事务
 *      外部存在事务:把当前事务挂起,开启新事务
 */
@Service(value = "integralServiceREQUIRES_NEW")
public class IntegralServiceImplREQUIRES_NEW extends ServiceImpl implements IntegralService {

    @Resource
    private IntegralMapper integralMapper;

    /**
     * REQUIRES_NEW传播行为
     * 场景一:外部事务存在异常,内部事务不存在异常,且没有处理异常
     *      预期结果:外部事务回滚,内部事务正常执行
     *      实际结果:外部事务回滚,内部事务正常执行
     *      对应方法:m1()
     *
     * 场景二:外部事务正常,内部事务有异常,但是在外部事务调用内部事务时,将内部事务的异常捕获并抛出去
     *      预期结果:外部事物和内部事务都会回滚
     *      实际结果:外部事物和内部事务都会回滚
     *      对应方法:m2()
     *      注意事项(坑):如果出现异常时,在catch代码块中将异常捕获自己处理了,没有往外抛,那么执行的结果是:外部事务提交,内部事务回滚
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    @Override
    public void addIntegral(IntegralDO updateIntegral) {
        m2(updateIntegral);
    }

    private void m2(IntegralDO updateIntegral) {
        integralMapper.insert(updateIntegral);
        System.out.println("REQUIRES_NEW==========================");
        int i = 100 / 0;
    }

    private void m1(IntegralDO updateIntegral) {
        integralMapper.insert(updateIntegral);
    }
}

你可能感兴趣的:(Spring全家桶面试系列,mysql,数据库)