Spring Transaction 源码解读
Spring Transaction 规范的maven坐标如下:
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>...</version></dependency>
该包提供了spring事务规范和默认的jta(java transaction api)实现(org.springframework.transaction.jta包下),具体的实现要看不同的组件,如spring-jdbc提供了数据库的事务实现。
Spring Transaction的核心接口为 事务管理器TransactionManager,不过该接口为标识接口,标识实现类是传统或Reactive的事务管理器。传统和Reactive的事务管理器分别对应PlatformTransactionManager和ReactiveTransactionManager,本文只关注传统的事务管理器。
spring-tx对传统的事务管理器PlatformTransactionManager提供了抽象实现AbstractPlatformTransactionManager,一般自定义事务管理器推荐继承该AbstractPlatformTransactionManager,如spring-jdbc的DataSourceTransactionManager就继承该抽象类。spring-tx事务管理器的uml类图如下:

关于spring事务的官方规范可以参考:Spring Transaction Management
PlatformTransactionManager
来看看该接口的注释说明:
central interface in Spring’s imperative transaction infrastructure. Typically, applications will work with either
TransactionTemplateor declarative transaction demarcation through AOP. It is recommended to derive from the providedorg.springframework.transaction.support.AbstractPlatformTransactionManagerclass, which pre-implements the defined propagation behavior and takes care of transaction synchronization handling.
public interface PlatformTransactionManager extends TransactionManager {// 根据指定的事务传播方式来决定返回正在运行的事务或新建一个事务TransactionStatus getTransaction(@Nullable TransactionDefinition definition)throws TransactionException;// 根据TransactionStatus提交事务,如果该事务被标记为rollback-only则执行回滚// 如果当前事务为嵌套的内层事务,则根据事务传播方式会忽略当前提交void commit(TransactionStatus status) throws TransactionException;// 实施回滚// 如果当前事务不是新事务(即嵌套事务),只需根据不同的事务传播方式设置外层事务的rollback-only属性。// Do not call rollback on a transaction if commit threw an exception.void rollback(TransactionStatus status) throws TransactionException;
}
TransactionStatus代表当前事务执行的状态。如果是声明式事务,事务状态信息存储在ThreadLocal中,参见TransactionAspectSupport,可通过静态方法TransactionAspectSupport#currentTransactionStatus获取当前事务状态。
AbstractPlatformTransactionManager
Abstract base class that implements Spring’s standard transaction workflow
该抽象类提供了以下工作流处理:
- 判断是否存在事务
- 应用事务传播方法
- 暂停或恢复事务
- 提交时检查rollback-only标识
- 对回滚做适当修改(直接回滚?还是设置rollback-only标识)
- 调用事务同步器回调方法(如果同步器开启)
关于事务同步器: Transaction synchronization is a generic mechanism for registering callbacks that get invoked at transaction completion time. This is mainly used internally by the data access support classes for JDBC, Hibernate, JPA, etc when running within a JTA transaction: They register resources that are opened within the transaction for closing at transaction completion time, allowing e.g. for reuse of the same Hibernate Session within the transaction. The same mechanism can also be leveraged for custom synchronization needs in an application.
事务同步器相当于一个事务扩展点,在事务的最后阶段提供了事务同步器的方法方便扩展,TransactionSynchronization接口提供了四个回调方法#beforeCommit #beforeCompletion #afterCommit #afterCompletion
事务同步器由
TransactionSynchronizationManager进行管理,所有的TransactionSynchronization和Resource(如DataSource的Connection资源,Mybatis的SqlSession资源)都放在ThreadLocal中,可以通过TransactionSynchronizationManager的静态方法进行注册、获取 资源信息和TransactionSynchronization
继承该类,必须重写以下抽象方法:
doGetTransactiondoBegindoCommitdoRollback
其他的方法不强制重写,可选 doSuspend,doResume, doSuspendSynchronization, doResumeSynchronization, doRollbackOnCommitException, doSetRollbackOnly, doCleanupAfterCompletion
编程式事务TransactionTemplate
TransactionTemplate为我们提供了编程式事务的模板,需要调用编程式事务时只需调用TransactionTemplate#execute或接口defaultTransactionOperations#executeWithoutResult,分别对应有返回值和无返回值的情况。两类方法最后都会调用TransactionTemplate#execute方法。
使用案例:
@Service
class TransactionService{// register somewhere@Resourceprivate TransactionTemplate transactionTemplate;@Resource private OneMapper oneMapper;@Resource private TwoMapper twoMapper;public void runSelfDefineTransaction(){transactionTemplate.setIsolationLevel(TransactionDefinition.PROPAGATION_REQUIRED);transactionTemplate.setTimeout(5);transactionTemplate.setReadOnly(false);transactionTemplate.executeWithoutResult(transactionStatus -> {oneMapper.insert(...);twoMapper.insert(...);});}
}
TransactionTemplate源码如下:
// 继承自TransactionDefinition,可修改配置
public class TransactionTemplate extends DefaultTransactionDefinitionimplements TransactionOperations, InitializingBean {@Nullableprivate PlatformTransactionManager transactionManager;...// 事务执行过程转化为TransactionCallback传入@Override@Nullablepublic <T> T execute(TransactionCallback<T> action) throws TransactionException {...TransactionStatus status = this.transactionManager.getTransaction(this);T result;try {// 执行自定义事务操作result = action.doInTransaction(status);}catch (RuntimeException | Error ex) {// Transactional code threw application exception -> rollbackrollbackOnException(status, ex);throw ex;}catch (Throwable ex) {// Transactional code threw unexpected exception -> rollbackrollbackOnException(status, ex);throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");}// 提交this.transactionManager.commit(status);return result;}
声明式事务
Spring声明式事务通过AOP实现,对注解了@Transactional注解的方法添加拦截器(注意使用方式,不然不生效,如方法必须public、避免类内调用),在拦截器中调用TransactionManager相关方法,参见TransactionInterceptor。
关于AOP,可以参考Spring AOP及代理类执行顺序
由于事务的拦截器没有实现Ordered接口、注解@Order、注解@Priority,所以默认最低优先级
声明式事务可以通过TransanctionAspectSupport工具类获取当前正在运行的事务
相关文章:
Spring Transaction 源码解读
Spring Transaction 规范的maven坐标如下: <dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>...</version></dependency>该包提供了spring事务规范和默认的jta(ja…...
[Netty] Channel和ChannelFuture和ChannelFutureListener (六)
文章目录1.Channel介绍2.ChannelFuture接口介绍3.GenericFutureListener接口介绍1.Channel介绍 NIO的Channel与Netty的Channel 不一样 Netty重新设计了Channel接口,并且给予了很多不同的实现, Channel是Netty网络的抽象类, 除了NIO中Channel所包含的网络I/O操作, 主动建立和关…...
条件渲染
组件经常需要根据不同条件显示不同内容。在React中,你可以使用类似于if语句、&&和?:运算符的JavaScript语法有条件地呈现JSX。你将学到:如何根据条件返回不同的JSX如何有条件地包含或排除一段JSX在React代码库中常见的条件语法快捷方式有条件地…...
springboot(10)异步任务
文章目录1、SpringBoot异步任务1.1使用注解EnableAsync开启异步任务支持1.2使用Async注解标记要进行异步执行的方法1.3controller测试2.异步任务相关限制3.1自定义 Executor3.1.1应用层级:3.1.2方法层级:3.2自定义 Executor (第二种方式)4.1异常处理4.1.…...
清华大学开源的chatGLM-6B部署实战
Windows部署 win10 通过wsl部署 常见问题: torch.cuda.OutOfMemoryError: CUDA out of memory. 在Windows的系统环境变量中增加 变量名:PYTORCH_CUDA_ALLOC_CONF 变量值:max_split_size_mb:32 文档书写时使用3090 24G显存配置,其他规格酌情调整 32 至其他值,如未设置变…...
通过矩阵从整体角度搞懂快速傅里叶变换原理
离散傅里叶变换公式 公式 f[k]∑n0N−1g[n]e−i(2π/N)kn,其中(0<n<N)f[k]\sum_{n0}^{N-1}g[n]e^{-i(2\pi/N)kn}, 其中(0<n<N) f[k]n0∑N−1g[n]e−i(2π/N)kn,其中(0<n<N) 逆变换公式 g[n]1N∑k0N−1f[k]ei(2π/N)kn,其中(0<k<N)g[n]\frac{1}{N}\…...
【C++从0到1】25、C++中嵌套使用循环
C从0到1全系列教程 1、实例代码 #include <iostream> // 包含头文件。 using namespace std; // 指定缺省的命名空间。int main() {// 超女分4个小组,每个小组有3名超女,在控制台显示每个超女的小组编号和组内编号。// 用一个循环…...
FastDFS与Nginx结合搭建文件服务器,并内网穿透实现公网访问
文章目录前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.1 …...
密集场景下的行人跟踪替代算法,头部跟踪算法 | CVPR 2021
一个不知名大学生,江湖人称菜狗 original author: Jacky LiEmail : 3435673055qq.com Time of completion:2023.4.8 Last edited: 2023.4.8 目录 摘要 主要内容 结果 这篇文章是CVPR 2021 的最新论文,文章的标题: 文章的主要内…...
Matlab与ROS(1/2)---服务端和客户端数据通信(五)
0. 简介 在前几讲我们讲了Matlab中的Message以及Topic的相关知识。而ROS主要支持的通信机制还有服务这一类。服务通过允许请求以及响应的通信方式,来给整个系统完成更紧密的耦合。服务客户端向服务服务器发送请求消息并等待响应。服务器将使用请求中的数据构造响应…...
数字化转型的避坑指南:细说数字化转型十二大坑
随着信息技术的快速发展,数字化转型已经成为许多企业发展的必经之路。然而,数字化转型过程中也存在许多坑,如果不谨慎处理,就可能导致企业陷入困境。本文将细说数字化转型的十二大坑,并提供相应的避坑指南。 1、不了解…...
pt05Encapsulationinherit
Encapsulation &inherit 封装继承 封装 向类外提供必要的功能,隐藏实现的细节, 代码可读性更高优势:简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。私有成员:作用:无需向类外提供…...
面向对象编程(基础)9:封装性(encapsulation)
目录 9.1 为什么需要封装? 而“高内聚,低耦合”的体现之一: 9.2 何为封装性? 9.3 Java如何实现数据封装 9.4 封装性的体现 9.4.1 成员变量/属性私有化 实现步骤: 成员变量封装的好处: 9.4.2 私有化…...
fate-serving-server增加取数逻辑并源码编译
1.什么是fate-serving-server? FATE-Serving 是一个高性能、工业化的联邦学习模型服务系统,专为生产环境而设计,主要用于在线推理。 2.fate-serving-server源码编译 下载fate-serving-serving项目(GitHub - FederatedAI/FATE-Serving: A scalable, h…...
循环队列、双端队列 C和C++
队列 目录 概念 实现方式 顺序队列 循环队列 队列的数组实现 用循环链表实现队列 STL 之 queue 实现队列 STL 之 dequeue 实现双端队列 概念 队列是一种特殊的线性表,它只允许在表的前端(称为队头,front)进行删除操作…...
正则表达式(语法+例子)
文章目录一、介绍二、语法1、匹配字符2、表示数量的字符3、边界字符4、其他字符5、转义字符三、例子1、邮箱2、用逗号分隔的数字集合1,23、允许一位小数4、20yy-mm-dd日期格式5、手机号6、匹配html、xml标签一、介绍 正则表达式(Regular Expression)&am…...
Properties和IO流集合的方法
方法名说明void load(InputStream inStream)从输入字节流读取属性列表(键和元素)void load(Reader reader)从输入字符流读取属性列表(键和元素对)void store(OutputStream out,String comments)将此属性列表(键和元素对…...
python 生成器、迭代器、动态新增属性及方法
目录 一、生成器 1、生成器定义 2、生成器存在的意义 3、创建生成器方式一(生成器表达式) 4. 创建生成器方式二(生成器函数) 1. 生成器函数 2. 生成器函数的工作原理 5. 总结 1. 什么是生成器 2. 生成器特点 二、迭代器…...
Java处理JSON
Java处理json有很多种方法,在这里总结一下。 1 Jackson Spring MVC 默认采用Jackson解析Json,出于最小依赖的考虑,也许Json解析第一选择就应该是Jackson。 1.1 引入的包 Jackson核心模块由三部分组成:jackson-core、jackson-a…...
58-Map和Set练习-LeetCode692前k个高频单词
题目 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。 示例 1: 输入: words ["i", "love", …...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
