当前位置: 首页 > news >正文

Spring 事务原理总结三

今天这篇文章,我想梳理一下Spring事务用到的几个核心组件。这些核心组件是我们理解Spring事务原理的基础。通过它们我们可以体会学习一下Spring设计者设计Spring事务时的基本思路。这些组件是:TransactionInfo、TransactionStatus、TransactionManager、TransactionAttribute、TransactionAttributeSource、ReactiveTransactionSupport等等。

首先让我们一起看一下TransactionInfo类。它是一个位于TransactionAspectSupport类中的内部类(这个类是上一节介绍的TransactionInterceptor的父类,TransactionInterceptor是一个增强类,用于对那些需要事务的方法进行增强)。TransactionInfo类的源码如下:

protected static final class TransactionInfo {@Nullableprivate final PlatformTransactionManager transactionManager;@Nullableprivate final TransactionAttribute transactionAttribute;private final String joinpointIdentification;@Nullableprivate TransactionStatus transactionStatus;@Nullableprivate TransactionInfo oldTransactionInfo;public TransactionInfo(@Nullable PlatformTransactionManager transactionManager,@Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {this.transactionManager = transactionManager;this.transactionAttribute = transactionAttribute;this.joinpointIdentification = joinpointIdentification;}public PlatformTransactionManager getTransactionManager() {Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");return this.transactionManager;}@Nullablepublic TransactionAttribute getTransactionAttribute() {return this.transactionAttribute;}/*** Return a String representation of this joinpoint (usually a Method call)* for use in logging.*/public String getJoinpointIdentification() {return this.joinpointIdentification;}public void newTransactionStatus(@Nullable TransactionStatus status) {this.transactionStatus = status;}@Nullablepublic TransactionStatus getTransactionStatus() {return this.transactionStatus;}/*** Return whether a transaction was created by this aspect,* or whether we just have a placeholder to keep ThreadLocal stack integrity.*/public boolean hasTransaction() {return (this.transactionStatus != null);}private void bindToThread() {// Expose current TransactionStatus, preserving any existing TransactionStatus// for restoration after this transaction is complete.this.oldTransactionInfo = transactionInfoHolder.get();transactionInfoHolder.set(this);}private void restoreThreadLocalStatus() {// Use stack to restore old transaction TransactionInfo.// Will be null if none was set.transactionInfoHolder.set(this.oldTransactionInfo);}@Overridepublic String toString() {return (this.transactionAttribute != null ? this.transactionAttribute.toString() : "No transaction");}
}

通过源码不难看出TransactionInfo是一个最终类,也没有继承或实现其他接口或类,其中的属性有PlatformTransactionManager、TransactionAttribute、TransactionStatus、TransactionInfo(通过其变量名可以知道其代表的是老事务。还记得《Spring事务原理总结一》这篇文章中提到的事务传播属性吗?其中提到的REQUIRES_NEW可能就是通过这个属性来实现的)等。

然后让我们再一起看一下TransactionStatus接口,其又继承了SavepointManager、Flushable、TransactionExecution等接口。下面是该接口的源码:

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {/*** Return whether this transaction internally carries a savepoint,* that is, has been created as nested transaction based on a savepoint.* <p>This method is mainly here for diagnostic purposes, alongside* {@link #isNewTransaction()}. For programmatic handling of custom* savepoints, use the operations provided by {@link SavepointManager}.* <p>The default implementation returns {@code false}.* @see #isNewTransaction()* @see #createSavepoint()* @see #rollbackToSavepoint(Object)* @see #releaseSavepoint(Object)*/default boolean hasSavepoint() {return false;}/*** Flush the underlying session to the datastore, if applicable:* for example, all affected Hibernate/JPA sessions.* <p>This is effectively just a hint and may be a no-op if the underlying* transaction manager does not have a flush concept. A flush signal may* get applied to the primary resource or to transaction synchronizations,* depending on the underlying resource.* <p>The default implementation is empty, considering flush as a no-op.*/@Overridedefault void flush() {}}

下图则是TransactionStatus接口的继承体系:

接着来让我们来看一下TransactionAttribute接口,该位于org.springframework.transaction.interceptor包中,先来看一下其源码:

public interface TransactionAttribute extends TransactionDefinition {/*** Return a qualifier value associated with this transaction attribute.* <p>This may be used for choosing a corresponding transaction manager* to process this specific transaction.* @since 3.0*/@NullableString getQualifier();/*** Return labels associated with this transaction attribute.* <p>This may be used for applying specific transactional behavior* or follow a purely descriptive nature.* @since 5.3*/Collection<String> getLabels();/*** Should we roll back on the given exception?* @param ex the exception to evaluate* @return whether to perform a rollback or not*/boolean rollbackOn(Throwable ex);}

下图是TransactionAttribute这个接口的继承体系(这里面我们中断关注RuleBasedTransactionAttribute这个类,第一次跟踪事务的执行代码时实际类型为RuleBasedTransactionAttribute):

最后再来看一下PlatformTransactionManager这个接口,该接口继承了TransactionManager接口,其有4个实现类,分别为AbstractPlatformTransactionManager、DataSourceTransactionManager、JdbcTransactionManager、JtaTransactionManager。个人理解它是一个管理接口。先看一下它的继承体系:

至此我们梳理了Spring事务涉及到的一些基本组件及其体系结构(这只是个人粗浅的认知,如果不全,还望各位大佬指正)。至于这些组件的作用,我们将在下一篇博客中逐一梳理。

相关文章:

  • MySQL中如何将字符串替换
  • C# 怎么判断屏幕是第几屏幕?屏幕是垂直还是水平?屏幕的分辨率?
  • 老版本O记12C上线前的一些调整
  • npm ERR! code CERT_HAS_EXPIRED
  • oracle数据回滚导致业务性能问题排查
  • 115.工业相机海康SDK开发指南(阅读)
  • IP数据云识别真实IP与虚假流量案例
  • 第二章 RocketMQ 的安装与启动
  • openGauss学习笔记-212 openGauss 数据库运维-日志参考
  • php工厂模式
  • 网络协议与攻击模拟_11DHCP欺骗防护
  • 服务器常遇的响应状态码
  • Linux 驱动开发基础知识—— 具体单板的 LED 驱动程序(五)
  • 代码随想录算法训练营day 23|第六章 二叉树part09
  • Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(三)
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 【译】理解JavaScript:new 关键字
  • JavaScript对象详解
  • PaddlePaddle-GitHub的正确打开姿势
  • PHP 的 SAPI 是个什么东西
  • PHP的类修饰符与访问修饰符
  • spring boot 整合mybatis 无法输出sql的问题
  • vue 配置sass、scss全局变量
  • 面试总结JavaScript篇
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 网页视频流m3u8/ts视频下载
  • 系统认识JavaScript正则表达式
  • 线上 python http server profile 实践
  • 译自由幺半群
  • RDS-Mysql 物理备份恢复到本地数据库上
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (12)Linux 常见的三种进程状态
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (3)llvm ir转换过程
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • .form文件_一篇文章学会文件上传
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • /usr/bin/env: node: No such file or directory
  • ::before和::after 常见的用法
  • ?
  • @Builder用法
  • @data注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @html.ActionLink的几种参数格式
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [ 渗透测试面试篇 ] 渗透测试面试题大集合(详解)(十)RCE (远程代码/命令执行漏洞)相关面试题
  • [20150904]exp slow.txt
  • [Android Studio 权威教程]断点调试和高级调试
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理
  • [elastic 8.x]java客户端连接elasticsearch与操作索引与文档
  • [GPT]Andrej Karpathy微软Build大会GPT演讲(上)--GPT如何训练
  • [ICCV2017]Neural Person Search Machines