【老王读Spring Transaction-3TransactionDefinition原理和源码解析】金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述老王读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;
TransactionAttributeTransactionAttribute 是 TransactionDefinition 的子接口,它增加了
rollbackOn()
方法,用于判断针对哪些异常进行事务回滚操作。它有两个比较常用的实现类:
DefaultTransactionAttribute
和 RuleBasedTransactionAttribute
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
是用来定义事务属性的。TransactionAttribute
是 TransactionDefinition
的子接口,它还有一个 rollbackOn()
方法,当出异常时,用于判断是否需要进行事务回滚。TransactionDefinition 有两个比较常用的实现类
DefaultTransactionAttribute
和 RuleBasedTransactionAttribute
。Spring 在读取了 @Transactional 注解之后,会将里面的事务属性保存在
RuleBasedTransactionAttribute
中。RuleBasedTransactionAttribute 用于判断针对指定的异常是否需要进行回滚,如果没有指定回滚规则,那么会使用 DefaultTransactionAttribute 来进行回滚判断。
如果本文对你有所帮助,欢迎点赞收藏!
有关 Spring 源码方面的问题欢迎留言一起交流...
阅读更多文章,请关注公众号: 老王学源码
文章图片
推荐阅读
- HTTP协议经典面试题整理及答案详解
- 状态机引擎在vivo营销自动化中的深度实践 | 引擎篇02
- 详解Apache Hudi如何配置各种类型分区
- POP3协议(电子邮件邮局协议)中UIDL和TOP命令在实际使用中的作用
- # yyds干货盘点 # 手把手教你使用Python网络爬虫获取基金信息
- 都2022年了,HDFS为何还如此能战!
- 微服务世纪难题(如何拆分单体())
- 硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战
- 再也不敢精通Java了——get/set篇