场景: updateStatus()是内部方法 create()是外部方法 create()嵌套updateStatus()后事务的传播行为控制
@Transactional
public void create() {
try {
testTwoService.updateStatus("nosusssssd","nosu","00f9d8530d8d4265ad35f0fd3ada1c42",1);
} catch (Exception e) {
System.out.println("外层捕获的异常打印开始。。。。。。。。。。。。。。。。。");
//运行时异常,事务正常会回滚
throw new RuntimeException(e);
}
// 保存项目数据
testOneMapper.create(project);
}
@Override
//@Transactional(propagation = Propagation.REQUIRES_NEW,noRollbackFor = Exception.class) 如果当前存在事务,把当前事务挂起。新建事务,出任何异常不回滚
//@Transactional(propagation = Propagation.REQUIRES_NEW,RollbackFor = Exception.class) //如果当前存在事务,把当前事务挂起。新建事务,出任何异常可以回滚
//@Transactional(propagation = Propagation.REQUIRES_NEW) //如果当前存在事务,把当前事务挂起。新建事务,默认出RuntimeException异常可以回滚,其他非RuntimeException不回滚
@Transactional(propagation = Propagation.REQUIRED)//如果当前没有事务,就新建一个事务。这是最常见的选择,支持使用外层事务。默认出RuntimeException异常可以回滚,其他非RuntimeException不回滚。和REQUIRES_NEW处理RollbackFor、noRollbackFor逻辑一样
//@Transactional(propagation = Propagation.NOT_SUPPORTED) // 如果外层存在事务,就把外层事务挂起,并且以非事务方式执行,出任何异常不回滚
//@Transactional(propagation = Propagation.MANDATORY) 必须在事务内部运行(否则抛异常),大白话就是外层必须有其他事务嵌套,并且支持使用外层事务 不常用
//@Transactional(propagation = Propagation.NEVER) 必须不在事务内部执行(否则抛异常),大白话就是外层不能有其他事务嵌套,以非事务方式执行 不常用
public void updateStatus(String userCode, String userName, String id, Integer status) {
//更新数据
testTwoMapper.updateStatus(userCode, userName, id, status);
}
目前总结:
总结一:默认内层标注@Transactional或者不标注的情况下,外层事务标注@Transactional,外层事务影响内层事务,外层事务执行失败,内层事务即使执行成功也会回滚;
总结二:如果想要内层事务不被外层事务执行结果影响,可以用
默认外层不标注@Transactional的情况下,内层标注@Transactional,外层事务执行失败,内层事务还是会执行成功不会回滚。
总结三:如果内层和外层事务都有事务,不想让外层事务影响到内层事务,或者说内层事务和外层事务互不影响,那就可以用以下方案解决,内层事务方法加如下标识:
@Transactional(propagation = Propagation.REQUIRES_NEW,noRollbackFor = Exception.class) 如果当前存在事务,把当前事务挂起。新建事务,出任何异常不回滚
@Transactional(propagation = Propagation.NOT_SUPPORTED) // 如果外层存在事务,就把外层事务挂起,并且以非事务方式执行,出任何异常不回滚