spring---transaction(2)---源代码分析(事务的定义TransactionDefinition)
写在前面
事务属性通过TransactionDefinition接口实现定义,主要有事务隔离级别、事务传播行为、事务超时时间、事务是否只读。
public interface TransactionDefinition { //事务传播行为类型:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。 int PROPAGATION_REQUIRED = 0; //事务传播行为类型:支持当前事务,如果当前没有事务,就以非事务方式执行。 int PROPAGATION_SUPPORTS = 1; //事务传播行为类型:当前如果有事务,Spring就会使用该事务;否则会抛出异常 int PROPAGATION_MANDATORY = 2; //事务传播行为类型:新建事务,如果当前存在事务,把当前事务挂起。 int PROPAGATION_REQUIRES_NEW = 3; //事务传播行为类型:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 int PROPAGATION_NOT_SUPPORTED = 4; //事务传播行为类型:即使当前有事务,Spring也会在非事务环境下执行。如果当前有事务,则抛出异常 int PROPAGATION_NEVER = 5; //事务传播行为类型:如果当前存在事务,则在嵌套事务内执行。 int PROPAGATION_NESTED = 6; //隔离级别:默认的隔离级别(对mysql数据库来说就是ISOLATION_ READ_COMMITTED,可以重复读) int ISOLATION_DEFAULT = -1; //隔离级别:读未提交(最低) int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED; //隔离级别:读提交 int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED; //隔离级别:可重复度 int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ; //隔离级别:序列化操作(最高) int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE; //默认事务的超时时间 int TIMEOUT_DEFAULT = -1; //获取事务的传播行为 int getPropagationBehavior(); //获取事务的隔离级别 int getIsolationLevel(); //获取超时时间 int getTimeout(); //是否只读 boolean isReadOnly(); //事务名称 String getName(); }
TransactionAttribute
TransactionAttribute是TransactionDefinition的实现接口
public interface TransactionAttribute extends TransactionDefinition { //事务的目标方法的完整限定方法名称 String getQualifier(); //对于给定的异常信息,是否回滚 boolean rollbackOn(Throwable ex); }
获取TransactionAttribute
在执行目标方法之前,获取事务之前,执行的目标增强。spring是从事务来源中获取事务的属性TransactionAttribute
spring 基于注解事务和声明事务的事务来源为: AnnotationTransactionAttributeSource、NameMatchTransactionAttributeSource
spring 基于注解事务和声明事务的TransactionDefinition默认实现都为是 RuleBasedTransactionAttribute
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable { final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); }
事务传播行为
Required:必须有逻辑事务,否则新建一个事务,使用PROPAGATION_REQUIRED指定,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务
RequiresNew:创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务(物理事务也是不同的)
Supports:支持当前事务,使用PROPAGATION_SUPPORTS指定,指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行
NotSupported:不支持事务,如果当前存在事务则暂停该事务,使用PROPAGATION_NOT_SUPPORTED指定,即以非事务方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行
Mandatory:必须有事务,否则抛出异常,使用PROPAGATION_MANDATORY指定,使用当前事务执行,如果当前没有事务,则抛出异常(IllegalTransactionStateException)
Never:不支持事务,如果当前存在是事务则抛出异常,使用PROPAGATION_NEVER指定,即以非事务方式执行,如果当前存在事务,则抛出异常(IllegalTransactionStateException)
Nested:嵌套事务支持,使用PROPAGATION_NESTED指定,如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务,嵌套事务使用数据库中的保存点来实现,即嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套事务回滚
事务只读:将事务标识为只读,只读事务不修改任何数据
左边为 正确的事务只读设置、右边有错误的只读设置。
对于错误的事务只读设置将抛出IllegalTransactionStateException异常,并伴随“Participating transaction with definition [……] is not marked as read-only……”信息,表示参与的事务只读属性设置错误。