来源于《互联网轻量级SSM框架解密:Spring、Spring MVC、MyBatis源码深度剖析》
内容
我们再来看看这个传播机制的特性。
Spring 事务默认是开启的,外层方法开启事务(Propagation.Required),事务会被传递到子方法中,哪怕子方法没有明确开启事务。如果子方法不想参与当前事务,则可以使用 Propagation.NOT_SUPPORTED,这个方法就会不使用事务,而且作用范围只在本方法内。
对事务传播性的描述可理解如下。
- (1)REQUIRED:支持当前事务,如果当前没有事务,就开启一
个事务。 - (2)SUPPORTS:支持当前事务,如果没有事务,就不开启新事
务,也有传播性,只在JTA场景下服务。 - (3)MANDATORY:(强制地)支持当前事务,如果前面没有开
启事务,则可能抛出异常。 - (4)REQUIRES_NEW:开启新事务,如果已存在事务,则挂起,
在本方法没有声明事务的子方法内不传播。 - (5)NOT_SUPPORTED:事务在本方法和没有声明事务的子方法
内不传播。 - (6)NEVER:如果有事务则抛出异常。
- (7)PROPAGATION_NESTED:如果当前存在事务,则在嵌套事
务内执行。如果当前没有事务,则与PROPAGATION_REQUIRED的特
性一致。
前6个策略类似于EJB CMT,第7个策略是Spring提供的一种特殊变
量。
现在支持 PROPAGATION_NESTED(嵌套事务传播特性)的事务
管理器有DataSourceTransactionManager及少数的JTA事务管理器。
PROPAGATION_NESTED(嵌套事务传播特性)在一般的业务场
景中较少用到,也较难理解,特别是嵌套事务的提交和回滚。
PROPAGATION_NESTED的事务传播特性如下: - (1)在外部事务提交时,提交嵌套事务;
- (2)在外部事务回滚时,嵌套事务也回滚;
- (3)在嵌套事务回滚时,外部事务不回滚,因为嵌套事务是外部
事务的子事务,有自己的隔离和锁,并且在开启嵌套事务时外部任务同
时创建了保存点用于回滚。
PROPAGATION_REQUIRES_NEW与 PROPAGATION_NESTED事
务传播机制的区别如下。 - (1)PROPAGATION_REQUIRES_NEW是自己开启一个事务,自
己提交和回滚自己的事务,与其他事务完全隔离、互不影响。 - (2)PROPAGATION_NESTED也开启一个事务(也叫嵌套事
务),但是这个事务依赖于开启它的外部事务,在外部事务提交后嵌套
事务才能提交,在外部事务回滚后才能回滚,嵌套事务是外部事务的一
部分,自己的失败不影响外部事务,事务之间的隔离级别较低。