mysql进阶:设置了事务注解 @Transactional但未生效|手动事务回滚

0. 引言

有同学遇到设置了事务,但是也报出了错误,但是一致未生效的问题,事务没有回滚,rollbackFor也设置成了捕捉全部报错Exception,那么这是怎么回事呢,其实原因很简单

1. 问题分析

首先我们要知道,事务的回滚是通过捕捉到错误了才执行的,如果本身没有报错是肯定不会进行回滚的。但还有一种情况,是大家比较容易忽略的,比如如下的一段代码,你觉得保存数据的操作会回滚吗?

    @Transactional(rollbackFor = Exception.class)
    public R save2(UserVO userVO) {
    
    
        User user = new User();
        // 拷贝属性
        BeanUtils.copyProperties(userVO, user);
        try {
    
    
            // 保存数据库
            saveUser(user);
            // 除数为0,将会报错
            int i = 1 / 0;
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return R.fail("操作失败");
        }
        return R.success("操作成功");
    }

答案是不会,为什么呢?因为你并没有将错误抛出,而是选择了catch,也就是自己处理报错,因此@Transactional自然捕捉不到报错,也就不会进行回滚了

我们可以更简单的将try,catch去除掉,让@Transactional捕捉到错误,定义一个全局的错误拦截器处理报错返回即可。

@Transactional(rollbackFor = Exception.class)
    public R save2(UserVO userVO) {
    
    
        User user = new User();
        // 拷贝属性
        BeanUtils.copyProperties(userVO, user);
        // 保存数据库
        saveUser(user);
        // 除数为0,将会报错
        int i = 1 / 0;
        return R.success("操作成功");
    }

当然,如果你实在需要手动的try,catch,可能你还需要在catch里实现一些自定义的操作, 那么这时候怎么办呢?

@Transactional也提供了手动进行事务回滚的方法:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

于是我们的代码就可以调整为

    @Transactional(rollbackFor = Exception.class)
    public R save2(UserVO userVO) {
    
    
        User user = new User();
        // 拷贝属性
        BeanUtils.copyProperties(userVO, user);
        try {
    
    
            // 保存数据库
            saveUser(user);
            // 除数为0,将会报错
            int i = 1 / 0;
        } catch (Exception e) {
    
    
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return R.fail("操作失败");
        }
        return R.success("操作成功");
    }

2. 其他事务未生效的场景

  • final、static 修饰的方法或者类不支持@Transactional
  • 非public 修饰的方法不支持@Transactional
  • 当前类不是bean,或者没有被spring容器管理
  • 数据库不支持事务
  • 事务的传播机制导致

猜你喜欢

转载自blog.csdn.net/qq_24950043/article/details/129373695