spring 事务一个被讹传很广说法是:一个事务方法不该该调用另外一个事务方法,不然将产生两个事务。结果形成开发人员在设计事务方法时束手束脚,生怕一不当心就踩到地雷。spring
其实这种是不认识 Spring 事务传播机制而形成的误解,Spring 对事务控制的支持统一在 TransactionDefinition 类中描述,该类有如下几个重要的接口方法:框架
int getPropagationBehavior():事务的传播行为spa
int getIsolationLevel():事务的隔离级别.net
int getTimeout():事务的过时时间设计
boolean isReadOnly():事务的读写特性。代理
很明显,除了事务的传播行为外,事务的其它特性 Spring 是借助底层资源的功能来完成的,Spring 无非只充当个代理的角色。可是事务的传播行为倒是 Spring 凭借自身的框架提供的功能,是 Spring 提供给开发者最珍贵的礼物,讹传的说法玷污了 Spring 事务框架最美丽的光环。orm
所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring 支持 7 种事务传播行为:接口
PROPAGATION_REQUIRED 若是当前没有事务,就新建一个事务,若是已经存在一个事务中,加入到这个事务中。这是最多见的选择。事务
PROPAGATION_SUPPORTS 支持当前事务,若是当前没有事务,就以非事务方式执行。资源
PROPAGATION_MANDATORY 使用当前的事务,若是当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,若是当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,若是当前存在事务,则抛出异常。
PROPAGATION_NESTED 若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则执行与 PROPAGATION_REQUIRED 相似的操做。
Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的状况。假设 ServiveX#methodX() 都工做在事务环境下(即都被 Spring 事务加强了),假设程序中存在以下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法经过 Spring 的事务传播机制都工做在同一个事务中。
事务的几种传播特性
1. PROPAGATION_REQUIRED: 若是存在一个事务,则支持当前事务。若是没有事务则开启 2. PROPAGATION_SUPPORTS: 若是存在一个事务,支持当前事务。若是没有事务,则非事务的执行 3. PROPAGATION_MANDATORY: 若是已经存在一个事务,支持当前事务。若是没有一个活动的事务,则抛出异常。 4. PROPAGATION_REQUIRES_NEW: 老是开启一个新的事务。若是一个事务已经存在,则将这个存在的事务挂起。 5. PROPAGATION_NOT_SUPPORTED: 老是非事务地执行,并挂起任何存在的事务。 6. PROPAGATION_NEVER: 老是非事务地执行,若是存在一个活动事务,则抛出异常 7. PROPAGATION_NESTED:若是一个活动的事务存在,则运行在一个嵌套的事务中. 若是没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行