Appearance
Spring 事务传播行为
Propagation
枚举,该枚举表示与@Transactional
事务注解一起使用的事务传播行为,对应于TransactionDefinition
接口。
REQUIRED
支持当前事务,如果不存在则创建一个新事务。这是@Transactional
事务注解的默认设置。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.REQUIRED
,结果如下:
b加入a的事务
无论哪个方法抛出异常,a和b都会回滚
不能捕获b抛出的异常,否则出现
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
。除非在catch
中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
,但a和b仍然都会回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.REQUIRED
,结果如下:
- b创建一个新事务
SUPPORTS
支持当前事务,如果不存在则以非事务方式执行。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.SUPPORTS
,结果如下:
b加入a的事务
无论哪个方法抛出异常,a和b都会回滚
不能捕获b抛出的异常,否则出现
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
。除非在catch
中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
,但a和b仍然都会回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.SUPPORTS
,结果如下:
- b以非事务方式执行
MANDATORY
支持当前事务,如果不存在则抛出异常。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.MANDATORY
,结果如下:
b加入a的事务
无论哪个方法抛出异常,a和b都会回滚
不能捕获b抛出的异常,否则出现
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
。除非在catch
中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
,但a和b仍然都会回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.MANDATORY
,结果如下:
- 在调用b时会出现
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
REQUIRES_NEW
创建一个新事务,如果存在当前事务,则挂起当前事务。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.REQUIRES_NEW
,结果如下:
b创建一个新事务,a抛出的异常不会导致b回滚
b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.REQUIRES_NEW
,结果如下:
- b创建一个新事务
NOT_SUPPORTED
以非事务方式执行,如果存在当前事务,则暂停当前事务。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.NOT_SUPPORTED
,结果如下:
b以非事务方式执行
b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.NOT_SUPPORTED
,结果如下:
- b以非事务方式执行
NEVER
以非事务方式执行,如果存在事务则抛出异常。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.NEVER
,结果如下:
在调用b时会出现
org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.NEVER
,结果如下:
- b以非事务方式执行
NESTED
如果当前事务存在,则在嵌套事务中执行,否则表现为REQUIRED
。
假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:
a方法有@Transactional
事务注解
如果b方法有Propagation.NESTED
,结果如下:
b在嵌套事务中执行
无论哪个方法抛出异常,a和b都会回滚
可以捕获b的异常来避免a回滚
a方法没有@Transactional
事务注解
如果b方法有Propagation.NESTED
,结果如下:
- b创建一个新事务,以
Propagation.REQUIRED
传播行为执行
总结
a调用b | a有事务且是默认传播行为 | a没有事务 |
---|---|---|
b事务传播行为是REQUIRED | 默认传播行为。b加入a的事务。无论哪个方法抛出异常,a和b都会回滚。不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only ;除非在catch 中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); ,但a和b仍然都会回滚 | b创建一个新事务 |
b事务传播行为是SUPPORTS | b加入a的事务。无论哪个方法抛出异常,a和b都会回滚。不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only ;除非在catch 中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); ,但a和b仍然都会回滚 | b以非事务方式执行 |
b事务传播行为是MANDATORY | b加入a的事务。无论哪个方法抛出异常,a和b都会回滚。不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only ;除非在catch 中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); ,但a和b仍然都会回滚 | 在调用b时会出现org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory' |
b事务传播行为是REQUIRES_NEW | b创建一个新事务,a抛出的异常不会导致b回滚。b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚 | b创建一个新事务 |
b事务传播行为是NOT_SUPPORTED | b以非事务方式执行。b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚 | b以非事务方式执行 |
b事务传播行为是NEVER | 在调用b时会出现org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never' 。b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚 | b以非事务方式执行 |
b事务传播行为是NESTED | b在嵌套事务中执行。无论哪个方法抛出异常,a和b都会回滚。可以捕获b抛出的异常来避免a回滚 | b创建一个新事务,以Propagation.REQUIRED 传播行为执行 |