Spring事务传播机制:
Spring在TransactionDefinition接口中规定了种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套时事务如何进行传播。
即协调已经有事务标识的方法之间的发生调用时的事务上下文的规则(是否要有独立的事务隔离级别和锁)。html
事务的嵌套概念:
所谓事务的嵌套就是两个事务方法之间相互调用。Spring事务开启,或者是基于接口的,或者是基于类的代理被建立(注意必定要是代理,
不能手动new一个对象,而且此类(有无接口都行)必定要被代理————Spring中的bean只要归入了IOC管理都是要被代理的)。
因此在同一个类中一个方法调用另外一个有事务的方法,事务是不会起做用的。spring
概述:
当咱们调用一个基于Spring的Service接口方法(如UserService#addUser())时,它将运行于Spring管理的事务环境中,
Service接口方法可能会在内部调用其它的Service接口方法以共同完成一个完整的业务操做,由于就会产生服务接口方法
嵌套调用的状况,Spring经过事务传播行为控制当前的事务如何传播到被嵌套调用的目标服务接口方法中。ide
事务传播是Spring进行事务管理的重要概念。在下文中将详细分析不一样事务传播行为的表现形式,掌握他们之间的区别。ui
1、事务传播行为种类idea
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套时事务如何进行传播:spa
以下为 org.springframework.transaction.TransactionDefinition接口。代理
package org.springframework.transaction; public interface TransactionDefinition { int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = 1; int ISOLATION_READ_COMMITTED = 2; int ISOLATION_REPEATABLE_READ = 4; int ISOLATION_SERIALIZABLE = 8; int TIMEOUT_DEFAULT = -1; int getPropagationBehavior();//事务的传播行为 int getIsolationLevel();//事务的隔离级别 int getTimeout();//事务的过时时间 boolean isReadOnly();//事务的读写特性 String getName();//获取名称 }
01. required:是Spring默认的事务传播行为。指定的方法必须在事务内执行,若是没有事务,自动建立事务并执行。code
02. support:有没有事务都执行,有事务就在事务中执行,不然直接执行。htm
03. mandatory:若是当前存在事务,就执行该事务,若是当前不存在事务,就抛出异常。对象
04. requires_new:老是建立新事务,若是当前方法存在事务,则将当前方法事务先挂起(先执行新建立的事务,再执行被挂起的当前方法自己的事务),直到新建立的事务执行完毕。
05. not_supported:不能再事务中执行,若是当前方法存在事务,则将当前方法事务挂起。
06. never :不能在事务中执行,若是当前方法存在事务,则会抛出异常。
07. nested:若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则执行与require相似的操做。
注意:
requires_new 是启动一个新的,不依赖于环境的“内部”事务。
这个事务将被彻底commited或者rollback而不依赖于外部事物,它拥有本身的隔离范围,本身的锁等等。当内部事务开始执行时,外务事务将会被挂起,内部事务结束时,外部事物将继续执行。
另外一方面,nested是开始一个“嵌套的”事务,它是已经存在的事务的一个真正的子事务。嵌套事务开始执行时,它将取得一个savepoint。若是这个事务执行失败,咱们将回滚到次savepoint,嵌套事务是外部事务的一部分,只有外部事务结束后嵌套事务才会被提交。(嵌套事务不可以提交,它必须经过外层事务来完成提交的动做,外层事务的回滚也会形成内部事务的回滚)
因而可知,requires_new 和 nested 最大的区别在于:
requires_new 彻底是一个新的事务,而nested则是外部事务的子事务,若是外部事务commit,嵌套事务也会被commit,这个规则一样适用于rollback。
借助例子理解,请查看 https://www.cnblogs.com/softidea/p/5962612.html