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

【老王读Spring Transaction-3TransactionDefinition原理和源码解析】金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述老王读Spring Transaction-3TransactionDefinition原理和源码解析相关的知识,希望能为你提供帮助。
@TOC
前言前文在分析@Transactional是如何被解析的 时候讲到,@Transactional 配置的事务属性被解析出来之后,被放在了 RuleBasedTransactionAttribute 当中。
TransactionAttribute 是 Spring 中用来定义事务属性的接口,它继承自 TransactionDefinition
下面就来详细分析一下 TransactionDefinition 的作用。
版本约定spring-tx 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)
正文首先看一下 TransactionDefinition 的类图:

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

文章图片

可以看到,TransactionAttribute 是 TransactionDefinition 的子接口,它是用来定义事务属性的。
详细的类图如下:
老王读Spring Transaction-3TransactionDefinition原理和源码解析

文章图片

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;

TransactionAttributeTransactionAttribute 是 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原理和源码解析

文章图片


    推荐阅读