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", …...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
32位寻址与64位寻址
32位寻址与64位寻址 32位寻址是什么? 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元(地址),其核心含义与能力如下: 1. 核心定义 地址位宽:CPU或内存控制器用32位…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...
uniapp获取当前位置和经纬度信息
1.1. 获取当前位置和经纬度信息(需要配置高的SDK) 调用uni-app官方API中的uni.chooseLocation(),即打开地图选择位置。 <button click"getAddress">获取定位</button> const getAddress () > {uni.chooseLocatio…...
