@Transactional 注解的方法内手动回滚事务

业务场景:

当前添加事务的方法内可能出现异常,但是需要去捕获这个异常,然后返回指定格式的数据。同时将当前方法内的所有改库操作都回滚

解决思路:
可能出现异常就将相关代码用try catch 捕获,但是捕获异常后事务就不会生效;所以希望在捕获异常后,手动去回滚事务,然后再组装指定的数据个数返回;

上代码:

@Transactional(rollbackFor = Exception.class)
    @Override
    /**
     * 测试事务回滚(手动回滚)
     */
    public Map<String,Object> updateAA(Long id) {
        Map<String,Object> resMap = new HashMap<>();
        try {
            //修改 A 表数据【直接调用注入的 dao 层的修改方法】
            aaMapper.updAA(id);
            //修改 B 表数据【调用 当前类 中的修改操作方法】
            updateBB(id);
            //修改 B 表数据【调用 其它类 中的修改操作方法】
            //test.updateBB(id);
            log.info("两张表都已修改成功!");
            //模拟异常
            int i = 1/0;
        } catch (Exception e) {
            log.info("出现异常"+e);
            //手动回滚事务**
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //组装异常情况下需要返回的数据
            resMap.put("code","500");
            resMap.put("msg","出现了异常");
            return resMap;
        }
        //组装正常常情况下需要返回的数据
        resMap.put("code","200");
        resMap.put("msg","操作成功");
        return resMap;
    }

测试点:
1,是否可以回滚当前类中未加@Transactional 注解的修改方法;【是】
2,是否可以回滚注入的其他类中中未加@Transactional 注解的修改方法;【是】
3,…待补充

知识点复习:

>>使用 @Transactional 注解事务失效的场景

1,注解用在了被 final、static 修饰的方法或者类上;
2,注解用在了非public 修饰的方法上;
3,当前类没有被Spring 管理;
4,多线程场调用;
5,数据库不支持事务;
6,异常被捕获;(*本示例中需要解决的问题)

>>事务的传播机制;

1,如果当前不存在事务,子方法就自己开启事务。父方法如果有事务,它就跟随父方法的事务被包裹其中。总之 REQUIRED 就是必须运行在事务中【为缺省值默认传播机制】

@Transactional(propagation = Propagation.REQUIRED)

2,如果当前存在了事务,它就也被包裹运行在这个事务中。如果父方法没有开启事务,它就以无事务运行

@Transactional(propagation = Propagation.SUPPORTS)

3,要求当前必须存在事务,否则这个子方法就抛出异常 IllegalTransactionStateException

@Transactional(propagation = Propagation.MANDATORY)

4,不管当前有没有事务,都不在那个事务中运行,自己一定会单独开启一个独立的事务运行

@Transactional(propagation = Propagation.REQUIRES_NEW)

5,如果当前已经存在了事务,则会挂起这个事务。子方法它坚决不在事务中运行

@Transactional(propagation = Propagation.NOT_SUPPORTED)

6,和 Propagation.MANDATORY 相反,子方法要求当前不能存在事务。否则它就抛出异常 IllegalTransactionStateException

Propagation.MANDATORY 相反,子方法要求当前不能存在事务。否则它就抛出异常 IllegalTransactionStateException

7,如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与 PROPAGATION_REQUIRED 类似的操作

@Transactional(propagation = Propagation.NESTED)

你可能感兴趣的:(学习拓展,java,spring,数据库)