美文网首页
@Transactional开启事务不生效,出错不回滚

@Transactional开启事务不生效,出错不回滚

作者: 沁园Yann | 来源:发表于2021-04-20 15:18 被阅读0次
原因一:自调用不走代理对象,用this.调用内层方法时注解是不生效的,例如下面的例子,u1可以插入成功,事务不生效。在控制器中的方法上加@Transactional,直接调用不生效也是这个原因。
  public void test() {
        try {
            this.insertUser();
        } catch (Exception e){
            log.error("执行出错啦",e.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    void insertUser() {
        User u1 = new User("Yann");
        insert(u1);
        int num = 5/0;
        User u2 = new User("Yoki");
        insert(u2);
    }

将上面例子改成通过代理对象的方式调用内层方法,事务就可以生效了

public void test() {
        UserService userService = (UserService) AopContext.currentProxy();
        try {
            userService.insertUser();
        } catch (Exception e){
            log.error("执行出错啦",e.getMessage());
        }
    }

   /**
     * 由于外层的方法通常也是要加事务的,所以内层的事务要
     * 加上propagation = Propagation.NESTED让内层事务不会影响到外层事务
    */
    @Transactional(propagation = Propagation.NESTED, rollbackFor = Exception.class)
    void insertUser() {
        User u1 = new User("Yann");
        insert(u1);
        int num = 5/0;
        User u2 = new User("Yoki");
        insert(u2);
    }
原因二:@Transactional注解只能应用到public修饰符上,其它修饰符不起作用,但不报错。
原因三:默认情况下此注解会对unchecked异常进行回滚,对checked异常不回滚。如果想要对所有异常都进行回滚,注解括号中添加 “rollbackFor = Exception.class” 指定异常类型就可以了

那什么是unchecked,什么是checked呢?通俗的说,编译器能检测到的是checked,检测不到的就是unchecked。
派生于Error或者RuntimeException(比如空指针,1/0)的异常称为unchecked异常。
继承自Exception的异常统称为checked异常,如 IOException、TimeoutException等。

@Transactional(rollbackFor = Exception.class)
    void insertUser() {
        User u1 = new User("Yann");
        insert(u1);
        int num = 5/0;
        User u2 = new User("Yoki");
        insert(u2);
    }
原因四:添加@Transactional注解的方法内部使用try-catch捕获异常了,没有抛出异常就不会回滚

相关文章

网友评论

      本文标题:@Transactional开启事务不生效,出错不回滚

      本文链接:https://www.haomeiwen.com/subject/vxrnlltx.html