SpringBoot 数据库事务7种传播行为

1. REQUIRED

如果当前方法的执行上下文中已经打开了事务,那么就使用当前这个事务。

如果当前没有事务,就创建一个新的。

如果多个方法都声明了 REQUIRED,并且他们嵌套调用,那么他们会共享同一个物理事务。就是 inner 产生了回滚,那么 outer 会跟着回滚。

Outer bean

@Autowired
private TestDAO testDAO;

@Autowired
private InnerBean innerBean;

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void testRequired(User user) {
  testDAO.insertUser(user);
  try{
    innerBean.testRequired();
  } catch(RuntimeException e){
    // handle exception
  }
}

Inner bean

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void testRequired() {
  throw new RuntimeException("Rollback this transaction!");
}

inner 声明了REQUIRED,并抛出了异常,outer 事务将同样回滚,因为他们是同一个事务。

2. REQUIRES_NEW

声明 REQUIRES_NEW 的话就会创建一个新的物理事务,内层事务的提交回滚都是独立于外层事务的。外层事务不受内层事务结果的影响,他们运行于独立的物理事务。

Outer bean

@Autowired
private TestDAO testDAO;

@Autowired
private InnerBean innerBean;

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void testRequiresNew(User user) {
  testDAO.insertUser(user);
  try{
    innerBean.testRequiresNew();
  } catch(RuntimeException e){
    // handle exception
  }
}

Inner bean

@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void testRequiresNew() {
  throw new RuntimeException("Rollback this transaction!");
}

inner 的回滚不影响 outer 的事务。当 inner 事务开启后,outer 事务会暂停,当 inner 事务结束后,outer 事务恢复。

3. NESTED

NESTED 使嵌套的事务使用相同的物理事务,但是对嵌套调用设置了保存点,所以 inner 事务可以独立于 outer 事务回滚。

此方式适用于使用 Spring JDBC 管理事务的场景。

4. SUPPORTS

支持事务,如果当前存在事务,就沿用当前事务,如果不存在,则继续采用无事务的方式运行。

5. MANDATORY

必须使用事务。如果当前没有事务,则会抛出异常,如果存在当前事务,就沿用当前事务。

6. NOT_SUPPORTED

不支持事务,当前存在事务时,将挂起事务,运行方法。

7. NEVER

不支持事务,如果当前方法存在事务,则抛出异常,否则继续使用无事务机制运行。

参考:
https://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容