同一个类中调用使事务失效

开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。

public String A(Integer id) {
        this.noticeMapper.insert(
                Notice.builder()
                        .id(id)
                        .content("a")
                        .createTime(new Date())
                        .showFlag(true)
                        .build()
        );
        log.info("notice success");
        this.B(id);
        return "成功";
    }


    @Transactional(rollbackFor = Exception.class)
    public void B(Integer id) {
        this.midUserShareMapper.insert(
                MidUserShare.builder()
                        .id(id)
                        .shareId(1)
                        .userId(1)
                        .build()
        );
        log.info("mid success");
        throw new IllegalArgumentException();
    }

B方法中抛出异常,正常应该会使事务回滚,然而并不会,其实这还是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
解决办法就是在A方法上加上 @Transactional(rollbackFor = Exception.class)注解

@Transactional(rollbackFor = Exception.class)
    public String A(Integer id) {
        this.noticeMapper.insert(
                Notice.builder()
                        .id(id)
                        .content("a")
                        .createTime(new Date())
                        .showFlag(true)
                        .build()
        );
        log.info("notice success");
        this.B(id);
        return "成功";
    }


    @Transactional(rollbackFor = Exception.class)
    public void B(Integer id) {
        this.midUserShareMapper.insert(
                MidUserShare.builder()
                        .id(id)
                        .shareId(1)
                        .userId(1)
                        .build()
        );
        log.info("mid success");
        throw new IllegalArgumentException();
    }

你可能感兴趣的:(spring)