@Transactional 学习笔记 - spring事务初级用法

@Transactional 学习笔记 - spring事务初级用法

业务场景: 同时操作两张表

业务要求同时操作两张表,要么同时成功,要么同时失败

准备工作: 准备两张表

@Transactional 学习笔记 - spring事务初级用法

情景1: 同一个方法里,依次插入张表
/**
     * 一个方法里插入两张表数据
     *
     * @return
     */

    @Override
    @Transactional
    public Boolean insertTogether() {

        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);

        TransactionalTwo transactionalTwo = new TransactionalTwo();
        transactionalTwo.setName("markeloff");
        transactionalTwoMapper.insert(transactionalTwo);

        return Boolean.TRUE;
    }

结果:无异常,都插入成功

情景2: 同一个方法里,依次插入两张表,任意地方发生异常
 @Override
    @Transactional
    public Boolean insertTogether() {

        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);

        if(true){
            log.info("--------------------------------------");
            throw new BusinessException(951022,"主动抛出业务异常");
        }

        TransactionalTwo transactionalTwo = new TransactionalTwo();
        transactionalTwo.setName("markeloff");
        transactionalTwoMapper.insert(transactionalTwo);

        return Boolean.TRUE;
    }
结果:发生异常,都两张表都插入失败

情景3: 方法一插入表1,调用方法二插入表2
@Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertOneAndOne() {
        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);

        insertTransactionalTwo();

        return Boolean.TRUE;
    }

    public void insertTransactionalTwo() {

            TransactionalTwo transactionalTwo = new TransactionalTwo();
            transactionalTwo.setName("markeloff");
            transactionalTwoMapper.insert(transactionalTwo);
    }
结果:无异常,都插入成功

情景4: 方法一插入表1,方法二插入表2 ,两个方法任意地方发生异常
@Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertOneAndOne() {
        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);

        insertTransactionalTwo();

        if(true){
            log.info("--------------------------------------");
            throw new BusinessException(951022,"主动抛出业务异常");
        }

        return Boolean.TRUE;
    }

    public void insertTransactionalTwo() {

            TransactionalTwo transactionalTwo = new TransactionalTwo();
            transactionalTwo.setName("markeloff");
            transactionalTwoMapper.insert(transactionalTwo);
    }
结果:发生异常, 两张表都插入失败

情景5: 方法一插入表1,方法一try调用方法二,方法二插入表2 ,try之前发生异常
@Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertOneAndOne() {
        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);
        if (true) {
            log.info("--------------------------------------");
            throw new BusinessException(951022, "主动抛出业务异常");
        }
        try {
            insertTransactionalTwo();
        } catch (Exception e) {

            e.printStackTrace();
        }
        return Boolean.TRUE;
    }

    public void insertTransactionalTwo() {

        TransactionalTwo transactionalTwo = new TransactionalTwo();
        transactionalTwo.setName("markeloff");
        transactionalTwoMapper.insert(transactionalTwo);
    }
结果:发生异常, 两张表都插入失败 。 异常发生在try语句之前,未被捕获,直接回滚

情景6: 方法一插入表1,方法一try调用方法二,方法二插入表2 ,try之后发生异常
@Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertOneAndOne() {
        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);

        try {
            insertTransactionalTwo();
        } catch (Exception e) {

            e.printStackTrace();
        }
        return Boolean.TRUE;
    }

    public void insertTransactionalTwo() {

        if (true) {
            log.info("--------------------------------------");
            throw new BusinessException(951022, "主动抛出业务异常");
        }

        TransactionalTwo transactionalTwo = new TransactionalTwo();
        transactionalTwo.setName("markeloff");
        transactionalTwoMapper.insert(transactionalTwo);
    }
结果:捕获异常, 表1插入成功 。 表2插入失败,因为表2的insert之前已经发生异常 , 但是异常被捕获, 并未回滚。如果异常发生在表2 insert后,则表2也能插入成功。

情景7: 方法一插入表1,方法一try调用方法二,方法二插入表2 ,try之后发生异常
@Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertOneAndOne() {
        TransactionalOne transactionalOne = new TransactionalOne();
        transactionalOne.setName("markeloff");
        transactionalOneMapper.insert(transactionalOne);

        try {
            insertTransactionalTwo();
        }finally {
            
        }
        return Boolean.TRUE;
    }

    public void insertTransactionalTwo() {

        if (true) {
            log.info("--------------------------------------");
            throw new BusinessException(951022, "主动抛出业务异常");
        }

        TransactionalTwo transactionalTwo = new TransactionalTwo();
        transactionalTwo.setName("markeloff");
        transactionalTwoMapper.insert(transactionalTwo);
    }
结果:发生异常,两张表都插入失败,原因是抛出的异常并没有catch语句捕获,直接回滚。
上一篇:Spring中声明式事务存在的优缺点以及注意事项!


下一篇:@Transactional回滚问题(try catch、嵌套)