老王读Spring Transaction-3TransactionDefinition原理和源码解析

Posted 老王学源码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了老王读Spring Transaction-3TransactionDefinition原理和源码解析相关的知识,希望对你有一定的参考价值。

@TOC

前言

前文在分析@Transactional是如何被解析的 时候讲到,@Transactional 配置的事务属性被解析出来之后,被放在了 RuleBasedTransactionAttribute 当中。

TransactionAttribute 是 Spring 中用来定义事务属性的接口,它继承自 TransactionDefinition

下面就来详细分析一下 TransactionDefinition 的作用。

版本约定

spring-tx 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)

正文

首先看一下 TransactionDefinition 的类图:

可以看到,TransactionAttribute 是 TransactionDefinition 的子接口,它是用来定义事务属性的。

详细的类图如下:

TransactionDefinition

定义 Spring 事务属性的接口。

TransactionDefinition 的定义如下:

public interface TransactionDefinition 
     /**
      * 返回事务传播行为(propagation behavior)
      * @see org.springframework.transaction.support.TransactionSynchronizationManager#isActualTransactionActive()
      */
     default int getPropagationBehavior() 
          return PROPAGATION_REQUIRED;
     

     /**
      * 返回事务隔离级别(isolation level)。  
      * 这个属性只适用于新启动的事务,即针对事务传播行为是 PROPAGATION_REQUIRED 或 PROPAGATION_REQUIRED_NEW 的情况
      * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction
      */
     default int getIsolationLevel() 
          return ISOLATION_DEFAULT;
     

     /** 返回事务超时时间。(单位:秒, 默认值: TIMEOUT_DEFAULT) */
     default int getTimeout() 
          return TIMEOUT_DEFAULT;
     

     /**
      * 返回是否是只读事务。  
      * 只读标志适用于任何事务上下文,不管是事务操作还是非事务操作。
      * @see org.springframework.transaction.support.TransactionSynchronization#beforeCommit(boolean)
      * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly()
      */
     default boolean isReadOnly() 
          return false;
     

     /**
      * 返回此事务的名称(可以为空)。
      * 对于 Spring 的声明性事务,默认暴露的事务名称是 “类的完全限定名.方法名称”。
      * @see org.springframework.transaction.interceptor.TransactionAspectSupport
      * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionName()
      */
     @Nullable
     default String getName() 
          return null;
     

TransactionDefinition 中还定义了事务传播行为事务隔离级别 的一些常量:

 /** 支持当前事务;如果不存在,则创建一个新的。(默认的事务传播行为)*/
 int PROPAGATION_REQUIRED = 0;

 /**
  * 支持当前事务;如果不存在,则以非事务方式执行。  
  * 注意: 它和没有事务执行是有区别的。需要谨慎使用!
  * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
  * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
  */
 int PROPAGATION_SUPPORTS = 1;

 /** 支持当前事务;如果当前不存在事务,则抛出异常。 */
 int PROPAGATION_MANDATORY = 2;

 /**
  * 创建一个新事务,并且挂起当前事务(如果当前事务存在的话)。
  * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
  */
 int PROPAGATION_REQUIRES_NEW = 3;

 /**
  * 不支持当前事务,始终以非事务方式执行。  
  * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
  */
 int PROPAGATION_NOT_SUPPORTED = 4;

 /** 不支持当前事务;如果当前事务存在,则抛出异常。 */
 int PROPAGATION_NEVER = 5;

 /**
  * 如果存在当前事务,则在嵌套事务中执行,否则,其行为与 PROPAGATION_REQUIRED 的行为类似。  
  * 注意:嵌套事务的实际创建只适用于特定的事务管理器,比如 DataSourceTransactionManager 在使用 JDBC 3.0 driver 时。
  * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
  */
 int PROPAGATION_NESTED = 6;

 /** 使用默认的事务隔离级别 */
 int ISOLATION_DEFAULT = -1;

 /** 读未提交。等同于: java.sql.Connection#TRANSACTION_READ_UNCOMMITTED */
 int ISOLATION_READ_UNCOMMITTED = 1;

 /** 读已提交。等同于: java.sql.Connection#TRANSACTION_READ_COMMITTED */
 int ISOLATION_READ_COMMITTED = 2;

 /** 可重复读。等同于: java.sql.Connection.TRANSACTION_REPEATABLE_READ */
 int ISOLATION_REPEATABLE_READ = 4;

 /** 等同于: java.sql.Connection#TRANSACTION_SERIALIZABLE */
 int ISOLATION_SERIALIZABLE = 8; 

 /** 默认的事务超时时间 */
 int TIMEOUT_DEFAULT = -1;

TransactionAttribute

TransactionAttribute 是 TransactionDefinition 的子接口,它增加了 rollbackOn() 方法,用于判断针对哪些异常进行事务回滚操作。

它有两个比较常用的实现类: DefaultTransactionAttributeRuleBasedTransactionAttribute

DefaultTransactionAttribute

DefaultTransactionAttribute 是 Spring 默认的事务属性实现,它只针对 RuntimeException 和 Error 进行回滚。

// DefaultTransactionAttribute#rollbackOn()
public boolean rollbackOn(Throwable ex) 
    return (ex instanceof RuntimeException || ex instanceof Error);

RuleBasedTransactionAttribute

RuleBasedTransactionAttribute 继承了 DefaultTransactionAttribute。
它表示的是基于规则的 TransactionAttribute,可以用于判断针对指定的异常是否需要回滚。

// 获胜规则是最浅的规则(即继承层次结构中最接近异常的规则)
public boolean rollbackOn(Throwable ex) 
    RollbackRuleAttribute winner = null;
    int deepest = Integer.MAX_VALUE;

    if (this.rollbackRules != null) 
        for (RollbackRuleAttribute rule : this.rollbackRules) 
            int depth = rule.getDepth(ex);
            if (depth >= 0 && depth < deepest) 
                deepest = depth;
                winner = rule;
            
        
    

    // User superclass behavior (rollback on unchecked) if no rule matches.
    if (winner == null) 
        return super.rollbackOn(ex);
    

    return !(winner instanceof NoRollbackRuleAttribute);

可以看到,RuleBasedTransactionAttribute 用于判断针对指定的异常是否需要进行回滚。
如果异常类存在继承关系,它也是支持的。
特别的,如果没有指定回滚规则,那么会使用 DefaultTransactionAttribute 来进行回滚判断。

小结

TransactionDefinition 是用来定义事务属性的。
TransactionAttributeTransactionDefinition 的子接口,它还有一个 rollbackOn() 方法,当出异常时,用于判断是否需要进行事务回滚。

TransactionDefinition 有两个比较常用的实现类 DefaultTransactionAttributeRuleBasedTransactionAttribute
Spring 在读取了 @Transactional 注解之后,会将里面的事务属性保存在 RuleBasedTransactionAttribute 中。

RuleBasedTransactionAttribute 用于判断针对指定的异常是否需要进行回滚,如果没有指定回滚规则,那么会使用 DefaultTransactionAttribute 来进行回滚判断。



如果本文对你有所帮助,欢迎点赞收藏
有关 Spring 源码方面的问题欢迎留言一起交流...

阅读更多文章,请关注公众号: 老王学源码

以上是关于老王读Spring Transaction-3TransactionDefinition原理和源码解析的主要内容,如果未能解决你的问题,请参考以下文章

老王读Spring IoC-5Spring IoC 小结——控制反转依赖注入

老王读Spring IoC-2Spring IoC之BeanDefinition扫描注册的原理

老王读Spring Transaction-4Spring事务管理的核心原理——PlatformTransactionManager&TransactionStatus

老王读Spring Transaction从EnableTransactionManagement顺藤摸瓜,研究@Transactional的实现原理

老王读Spring Transaction-6spring-tx与DataSource连接池整合的原理

#yyds干货盘点# 老王读Spring AOP-4Spring AOP 与Spring IoC 结合的过程 && ProxyFactory 解析