Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

关于事务传播行为中TransactionDefinition.PROPAGATION_NESTED案例描述错误 #2597

Open
JoeyChanMiao opened this issue Feb 13, 2025 · 4 comments

Comments

@JoeyChanMiao
Copy link
Contributor

JoeyChanMiao commented Feb 13, 2025

Image
bMethod()作为aMethod()的嵌套子事务,此时bMethod()出现异常,按照案例代码aMethod()应该会感知异常致使整体事务回滚;
Spring 事务详解

@Snailclimb
Copy link
Owner

Image bMethod()作为aMethod()的嵌套子事务,此时bMethod()出现异常,按照案例代码aMethod()应该会感知异常致使整体事务回滚; Spring 事务详解

应该不会回滚吧?NESTED 适用:允许部分操作失败不影响整体事务(如日志记录失败不影响主业务)。

@JoeyChanMiao
Copy link
Contributor Author

Image bMethod()作为aMethod()的嵌套子事务,此时bMethod()出现异常,按照案例代码aMethod()应该会感知异常致使整体事务回滚; Spring 事务详解

应该不会回滚吧?NESTED 适用:允许部分操作失败不影响整体事务(如日志记录失败不影响主业务)。

写了个demo验证了一下
验证代码如下:

@Service
public class A {

    @Resource
    private UserService userService;

    @Resource
    private B b;

    @Transactional(propagation = Propagation.REQUIRED)
    public void aMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("aMethod-Insert");
        userDO.setAge(1);
        userService.save(userDO);
        //bMethod()方法发生异常
        b.bMethod();
    }

}

@Service
class B {

    @Resource
    private UserService userService;

    @Transactional(propagation = Propagation.NESTED)
    public void bMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("bMethod-Insert");
        userDO.setAge(2);
        userService.save(userDO);
        throw new RuntimeException("methodB发生异常");
    }
}

结果如下:
Image
aMethod()和bMethod()均未插入;

【NESTED 适用:允许部分操作失败不影响整体事务】这句话按我的理解是嵌套子事务不会导致整体事务的回滚,前提是子事务bMethod()方法自己要处理异常或异常被外层aMethod()方法处理;
验证代码如下:

@Service
public class A {

    @Resource
    private UserService userService;

    @Resource
    private B b;

    @Transactional(propagation = Propagation.REQUIRED)
    public void aMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("aMethod-Insert");
        userDO.setAge(1);
        userService.save(userDO);
        //bMethod()方法发生异常
        try {
            b.bMethod();
        }catch (Exception e){
            System.out.println("bMethod()方法异常处理");
        }
    }

}

@Service
class B {

    @Resource
    private UserService userService;

    @Transactional(propagation = Propagation.NESTED)
    public void bMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("bMethod-Insert");
        userDO.setAge(2);
        userService.save(userDO);
        throw new RuntimeException("methodB发生异常");
    }
}

结果如下:
Image
aMethod()方法插入成功,bMethod()方法未插入;

另外:在文章最后参考文章中Spring 事务传播行为详解也有场景验证,和我验证的结果一致;

@Snailclimb
Copy link
Owner

Image bMethod()作为aMethod()的嵌套子事务,此时bMethod()出现异常,按照案例代码aMethod()应该会感知异常致使整体事务回滚; Spring 事务详解

应该不会回滚吧?NESTED 适用:允许部分操作失败不影响整体事务(如日志记录失败不影响主业务)。

写了个demo验证了一下 验证代码如下:

@Service
public class A {

    @Resource
    private UserService userService;

    @Resource
    private B b;

    @Transactional(propagation = Propagation.REQUIRED)
    public void aMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("aMethod-Insert");
        userDO.setAge(1);
        userService.save(userDO);
        //bMethod()方法发生异常
        b.bMethod();
    }

}

@Service
class B {

    @Resource
    private UserService userService;

    @Transactional(propagation = Propagation.NESTED)
    public void bMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("bMethod-Insert");
        userDO.setAge(2);
        userService.save(userDO);
        throw new RuntimeException("methodB发生异常");
    }
}

结果如下: Image aMethod()和bMethod()均未插入;

【NESTED 适用:允许部分操作失败不影响整体事务】这句话按我的理解是嵌套子事务不会导致整体事务的回滚,前提是子事务bMethod()方法自己要处理异常或异常被外层aMethod()方法处理; 验证代码如下:

@Service
public class A {

    @Resource
    private UserService userService;

    @Resource
    private B b;

    @Transactional(propagation = Propagation.REQUIRED)
    public void aMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("aMethod-Insert");
        userDO.setAge(1);
        userService.save(userDO);
        //bMethod()方法发生异常
        try {
            b.bMethod();
        }catch (Exception e){
            System.out.println("bMethod()方法异常处理");
        }
    }

}

@Service
class B {

    @Resource
    private UserService userService;

    @Transactional(propagation = Propagation.NESTED)
    public void bMethod(){
        UserDO userDO = new UserDO();
        userDO.setName("bMethod-Insert");
        userDO.setAge(2);
        userService.save(userDO);
        throw new RuntimeException("methodB发生异常");
    }
}

结果如下: Image aMethod()方法插入成功,bMethod()方法未插入;

另外:在文章最后参考文章中Spring 事务传播行为详解也有场景验证,和我验证的结果一致;

嗯嗯,不错的,费心了。如果可以的话,欢迎对这部分内容进行简单修正和完善,欢迎提交PR呀!

@JoeyChanMiao
Copy link
Contributor Author

好的,有时间我提交一下PR;

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants