Spring 事务传播行为

事务是逻辑处理原子性的保证手段,通过使用事务控制,可以极大的避免出现逻辑处理失败导致的脏数据等问题。

事务最重要的两个特性,是事务的传播行为和数据隔离级别。传播级别定义的是事务的控制范围,事务隔离级别定义的是事务在数据库读写方面的控制范围。

以下是事务的7种传播行为:

1) PROPAGATION_REQUIRED :默认的spring事务传播级别,使用该级别的特点是,如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行

测试代码:
  1. 场景一:父方法有事务,父事务抛异常,子事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码回滚

  2. 场景二:父方法有事务,子事务抛异常,父事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  3. 场景三:父方法有事务,父事务、子事务都抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  4. 场景四:父方法有事务,父事务、子事务都不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码不回滚

  5. 场景五:父方法没有事务,父事务不抛异常、子事务抛异常

    public void transactional(){
        userManager.saveUser();
         User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  6. 场景六:父方法没有事务,父方法抛异常,子事务不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

  7. 场景七:父方法没有事务,父方法、子事务都抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:父方法、子事务代码都回滚

  8. 场景八:父方法没有事务,父方法、子事务都不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

总结:如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行

2)PROPAGATION_SUPPORTS :该传播级别的特点是,如果上下文存在事务,则支持事务加入事务,如果没有事务,则使用非事务的方式执行。

测试代码:
  1. 场景一:父方法有事务,父事务抛异常,子事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码回滚

  2. 场景二:父方法有事务,子事务抛异常,父事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  3. 场景三:父方法有事务,父事务、子事务都抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  4. 场景四:父方法有事务,父事务、子事务都不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码不回滚

  5. 场景五:父方法没有事务,父事务不抛异常、子事务抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码不回滚

  6. 场景六:父方法没有事务,父方法抛异常,子事务不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

  7. 场景七:父方法没有事务,父方法、子事务都抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:父方法、子事务代码都不回滚

  8. 场景八:父方法没有事务,父方法、子事务都不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

总结:该传播级别的特点是,如果上下文存在事务,则支持事务加入事务,如果没有事务,则使用非事务的方式执行

3)PROPAGATION_MANDATORY :该传播级别的特点是,该级别的事务要求上下文中必须要存在事务,否则就会抛出异常!

  1. 场景一:父方法有事务,父事务抛异常,子事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码回滚

  2. 场景二:父方法有事务,子事务抛异常,父事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  3. 场景三:父方法有事务,父事务、子事务都抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  4. 场景四:父方法有事务,父事务、子事务都不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码不回滚

  5. 场景五:父方法没有事务

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:报异常

    org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation ‘mandatory’

总结:该传播级别的特点是,该级别的事务要求上下文中必须要存在事务,否则就会抛出异常!

4)PROPAGATION_REQUIRES_NEW :该传播级别的特点是,每次都要一个新事务,该传播级别的特点是,每次都会新建一个事务,并且同时将上下文中的事务挂起,执行当前新建事务完成以后,上下文事务恢复再执行。(一个事务单独提交)

测试代码:
  1. 场景一:父方法有事务,父事务抛异常,子事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:子事务提交、父事务回滚

  2. 场景二:父方法有事务,子事务抛异常,父事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  3. 场景三:父方法有事务,父事务、子事务都抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  4. 场景四:父方法有事务,父事务、子事务都不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码不回滚

  5. 场景五:父方法没有事务,父事务不抛异常、子事务抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:代码回滚

  6. 场景六:父方法没有事务,父方法抛异常,子事务不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

  7. 场景七:父方法没有事务,父方法、子事务都抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:父方法、子事务代码都回滚

  8. 场景八:父方法没有事务,父方法、子事务都不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

总结:该传播级别的特点是,每次都要一个新事务,该传播级别的特点是,每次都会新建一个事务,并且同时将上下文中的事务挂起,执行当前新建事务完成以后,上下文事务恢复再执行。(一个事务单独提交)
5)PROPAGATION_NOT_SUPPORTED :该传播级别的特点是,上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务。

测试代码:
  1. 场景一:父方法有事务,父事务抛异常,子事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:子事务提交、父事务回滚

  2. 场景二:父方法有事务,子事务抛异常,父事务不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:子事务提交、父事务回滚

  3. 场景三:父方法有事务,父事务、子事务都抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:子事务提交、父事务回滚

  4. 场景四:父方法有事务,父事务、子事务都不抛异常

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:代码不回滚

  5. 场景五:父方法没有事务,父事务不抛异常、子事务抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:子事务提交、父事务回滚

  6. 场景六:父方法没有事务,父方法抛异常,子事务不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

  7. 场景七:父方法没有事务,父方法、子事务都抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:子事务提交、父事务回滚

  8. 场景八:父方法没有事务,父方法、子事务都不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

总结:该传播级别的特点是,上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务

6)PROPAGATION_NEVER :该传播级别的特点是,上下文中不能存在事务,一旦有事务,就抛出runtime异常,强制停止执行!这个级别上辈子跟事务有仇。

测试代码:
  1. 场景一:父方法有事务

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NEVER)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:报异常

    org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation ‘never’

  2. 场景二:父方法没有事务,父事务不抛异常、子事务抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NEVER)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:子事务提交、父事务回滚

  3. 场景三:父方法没有事务,父方法抛异常,子事务不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NEVER)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:子事务提交、父事务回滚

  4. 场景四:父方法没有事务,父方法、子事务都抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NEVER)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
        throw new BizCoreException("回滚测试");
    }
    

    总结:子事务提交、父事务回滚

  5. 场景五:父方法没有事务,父方法、子事务都不抛异常

    public void transactional(){
        userManager.saveUser();
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-父事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NEVER)
    public void saveUser(){
        User user = new User();
        user.setOpenId(IdUtil.fastSimpleUUID());
        user.setUsername("admin-子事务");
        user.setPassword("123456");
        userDAO.save(user);
    }
    

    总结:父方法、子事务代码都不回滚

总结:该传播级别的特点是,上下文中不能存在事务,一旦有事务,就抛出runtime异常,强制停止执行!这个级别上辈子跟事务有仇

7)PROPAGATION_NESTED ,该传播级别的特点是,如果上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring框架中,事务传播行为用于定义一个方法调用时如何参与到已存在的事务中,或者如何创建一个新的事务Spring框架提供了多种事务传播行为选项,可以通过@Transactional注解或者编程式事务管理来配置。 以下是一些常见的Spring事务传播行为: 1. REQUIRED(默认):如果当前存在事务,则入该事务;如果没有事务,则创建一个新的事务。这是最常用的传播行为,适合大多数情况。 2. SUPPORTS:如果当前存在事务,则入该事务;如果没有事务,则以非事务的方式执行。适用于不需要强制要求事务的场景。 3. MANDATORY:如果当前存在事务,则入该事务;如果没有事务,则抛出异常。适用于必须在一个已存在的事务中执行的场景。 4. REQUIRES_NEW:创建一个新的事务,并挂起当前的事务(如果存在)。适用于需要独立的事务执行的场景。 5. NOT_SUPPORTED:以非事务的方式执行操作,挂起当前的事务(如果存在)。适用于不需要事务支持的场景。 6. NEVER:以非事务的方式执行操作,如果当前存在事务,则抛出异常。适用于必须在没有事务的环境下执行的场景。 7. NESTED:如果当前存在事务,则在嵌套事务中执行;如果没有事务,则创建一个新的事务。嵌套事务是独立于外部事务的内部事务,它可以独立地进行提交或回滚,但是如果外部事务回滚,嵌套事务也会回滚。 通过选择合适的事务传播行为,可以确保在不同的方法调用中有效地管理事务,保证事务的一致性和可靠性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值