http://www.iteye.com/topic/35907ui
PROPAGATION_REQUIRED -- 支持当前事务,若是当前没有事务,就新建一个事务。这是最多见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,若是当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,若是当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,若是当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,若是当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则进行与PROPAGATION_REQUIRED相似的操做。
前六个策略相似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManagerspa
PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被彻底 commited 或 rolled back 而不依赖于外部事务, 它拥有本身的隔离范围, 本身的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.
另外一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 若是这个嵌套事务失败, 咱们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交. 事务
PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被彻底 commited 或 rolled back 而不依赖于外部事务, 它拥有本身的隔离范围, 本身的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.
另外一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 若是这个嵌套事务失败, 咱们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交.
因而可知, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 彻底是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 若是外部事务 commit, 潜套事务也会被 commit, 这个规则一样适用于 roll back. get
因而可知,it
PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于,io
PROPAGATION_REQUIRES_NEW 彻底是一个新的事务, 而require
PROPAGATION_NESTED 则是外部事务的子事务, 若是外部事务 commit, 潜套事务也会被 commit,变量
这个规则一样适用于 roll back. 配置
固然, 就算全部嵌套事务都已经成功, 外部事务仍是可能由于嵌套事务的执行结果而致使失败, 此时整个事务都要 roll back ,这也是嵌套事务的重要特性之一, 即外部事务和嵌套事务互相影响程序
只有须要根据子事务的执行状况进行分支处理的状况下才是nested的用武之地, savepoint是嵌套事务回滚的实现方式 须要注意的是使用它的限制条件
使用嵌套事务是有前提的,就是该嵌套事务可能须要作分支处理。不然用 PROPAGATION_REQUIRED 就足够了,若是子事务有异常,直接回滚。
nested 能够在外层rollback全部内层的事务。requiresnew 不行。
例子:
PROPAGATION_REQUIRES_NEW 时 ServiceB.methodB 没办法回滚到它执行以前的 SavePoint, 这时已经产生了一些脏数据, 而这些脏数据将可能致使后面的程序执行出错
对于PROPAGATION_NESTED 的嵌套事务而言,若是 ServiceB.methodB()异常,会会回滚到上一个savepoint点,外层事务A,能够捕获,处理ServiceC.methodC(),可是对于ServiceA.methodA()异常,会回滚整个嵌套的事务