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