Spring事务管理实现机制

news2025/5/11 7:35:23

Spring通过一系列精妙的抽象和实现来完成事务的融入、挂起和嵌套操作。下面我将详细解析Spring如何实现这些事务行为。

1. 核心组件

Spring事务管理的核心组件包括:

  • PlatformTransactionManager:事务管理器的抽象接口

  • TransactionDefinition:定义事务属性(传播行为、隔离级别等)

  • TransactionStatus:表示事务状态

  • TransactionSynchronizationManager:事务同步管理器(线程绑定资源管理)

2. 事务融入(REQUIRED)实现

当传播行为为PROPAGATION_REQUIRED时:

// 简化版AbstractPlatformTransactionManager处理逻辑
if (isExistingTransaction(transaction)) {
    // 已存在事务:融入现有事务
    return handleExistingTransaction(def, transaction, debugEnabled);
} else {
    // 不存在事务:创建新事务
    return startTransaction(def, transaction, debugEnabled, suspendedResources);
}

融入过程

  1. 通过TransactionSynchronizationManager判断当前线程是否已有事务

  2. 如果有,获取当前事务信息并加入

  3. 通过线程绑定机制(ThreadLocal)共享同一事务资源

3. 事务挂起(REQUIRES_NEW/NOT_SUPPORTED)实现

当传播行为需要挂起当前事务时:

// 挂起当前事务的典型实现
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) {
    // 1. 从当前线程解绑事务资源
    List<TransactionSynchronization> suspendedSynchronizations = 
        TransactionSynchronizationManager.getSynchronizations();
    
    // 2. 解绑所有事务相关资源
    Map<Object, Object> suspendedResources = 
        TransactionSynchronizationManager.unbindResource(obtainTransactionSynchronizationRegistry());
    
    // 3. 重置线程绑定状态
    TransactionSynchronizationManager.clear();
    
    return new SuspendedResourcesHolder(
        suspendedResources, suspendedSynchronizations);
}

挂起过程

  1. 保存当前事务状态到SuspendedResourcesHolder

  2. 从TransactionSynchronizationManager清理线程绑定

  3. 后续操作将在无事务或新事务中执行

4. 事务嵌套(NESTED)实现

对于PROPAGATION_NESTED的实现:

// DataSourceTransactionManager中的实现
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
    if (!useSavepointForNestedTransaction()) {
        throw new NestedTransactionNotSupportedException(...);
    }
    // 创建保存点
    Object savepoint = getSavepointManager().createSavepoint();
    return prepareTransactionStatus(definition, transaction, false, true, debugEnabled, savepoint);
}

嵌套实现关键点

  1. 检查数据库是否支持保存点

  2. 通过JDBC Savepoint机制实现

  3. 内部事务回滚只回滚到保存点

  4. 外部事务回滚会导致全部回滚

5. 底层实现技术

Spring实现这些行为的底层技术包括:

5.1 线程绑定机制

  • 使用TransactionSynchronizationManager维护线程绑定资源

  • 基于ThreadLocal存储当前事务状态

  • 关键方法:bindResource/unbindResource

5.2 JDBC抽象

  • 对Connection的包装(TransactionAwareDataSourceProxy)

  • 保存点管理(通过Connection#setSavepoint)

  • 事务隔离级别控制

5.3 事务同步

  • TransactionSynchronization接口

  • 注册回调处理(如afterCommit, afterCompletion)

  • 保证资源清理和状态恢复

6. 典型处理流程

// 简化版事务处理流程
public final TransactionStatus getTransaction(TransactionDefinition definition) {
    // 1. 获取或创建事务
    Object transaction = doGetTransaction();
    
    // 2. 检查当前线程是否已有事务
    if (isExistingTransaction(transaction)) {
        // 处理已存在事务的情况(融入/挂起/嵌套等)
        return handleExistingTransaction(definition, transaction, debugEnabled);
    }
    
    // 3. 处理无事务的情况
    return startTransaction(definition, transaction, debugEnabled, null);
}

7. 不同传播行为的实现对比

传播行为实现机制
REQUIRED加入现有事务或新建事务(线程绑定同一Connection)
REQUIRES_NEW挂起当前事务→新建事务→新Connection绑定到线程→原事务保存在SuspendedResourcesHolder
NESTED使用JDBC Savepoint机制(不创建新Connection)
NOT_SUPPORTED挂起当前事务→无事务执行→恢复原事务
MANDATORY强制检查当前是否存在事务

8. 事务恢复机制

当事务挂起后需要恢复时:

protected final void resume(@Nullable Object transaction, 
                          @Nullable SuspendedResourcesHolder resourcesHolder) {
    if (resourcesHolder != null) {
        // 恢复线程绑定的资源
        TransactionSynchronizationManager.bindResource(
            obtainTransactionSynchronizationRegistry(), 
            resourcesHolder.getSuspendedResources());
        // 恢复同步器
        resourcesHolder.register();
    }
}

Spring通过这些精细的控制机制,实现了灵活的事务传播行为,为复杂业务场景提供了可靠的事务管理能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚假AI工具通过Facebook广告传播新型Noodlophile窃密木马

网络安全公司Morphisec的研究人员发现&#xff0c;攻击者正利用虚假人工智能&#xff08;AI&#xff09;平台传播名为Noodlophile Stealer的新型信息窃取木马。这种复杂攻击手法利用AI工具的热度诱骗用户下载恶意软件&#xff0c;窃取浏览器凭证、加密货币钱包&#xff0c;并可…

麦科信获评CIAS2025金翎奖【半导体制造与封测领域优质供应商】

在苏州举办的2025CIAS动力能源与半导体创新发展大会上&#xff0c;深圳麦科信科技有限公司凭借在测试测量领域的技术积累&#xff0c;入选半导体制造与封测领域优质供应商榜单。本届大会以"新能源芯时代"为主题&#xff0c;汇集了来自功率半导体、第三代材料应用等领…

指针运算典型例题解析

1.题目1 该代码运行的结果是什么&#xff1f; #include <stdio.h> int main() { int a[5] { 1, 2, 3, 4, 5 }; int *ptr (int *)(&a 1); printf( "%d,%d", *(a 1), *(ptr - 1)); return 0; } 解析&#xff1a; 运行结果&#xff1a; 2.题目2 在X86…

DAX 权威指南1:DAX计算、表函数与计算上下文

参考《DAX 权威指南 第二版》 文章目录 二、DAX简介2.1 理解 DAX 计算2.2 计算列和度量值2.3 变量2.3.1 VAR简介2.3.2 VAR的特性 2.4 DAX 错误处理2.4.1 DAX 错误类型2.4.1.1 转换错误2.4.1.2 算术运算错误2.4.1.3 空值或 缺失值 2.4.2 使用IFERROR函数拦截错误2.4.2.1 安全地进…

使用 NV‑Ingest、Unstructured 和 Elasticsearch 处理非结构化数据

作者&#xff1a;来自 Elastic Ajay Krishnan Gopalan 了解如何使用 NV-Ingest、Unstructured Platform 和 Elasticsearch 为 RAG 应用构建可扩展的非结构化文档数据管道。 Elasticsearch 原生集成了行业领先的生成式 AI 工具和提供商。查看我们的网络研讨会&#xff0c;了解如…

20250508在WIN10下使用移远的4G模块EC200A-CN直接上网

1、在WIN10/11下安装驱动程序&#xff1a;Quectel_Windows_USB_DriverA_Customer_V1.1.13.zip 2、使用移远的专用串口工具&#xff1a;QCOM_V1.8.2.7z QCOM_V1.8.2_win64.exe 3、配置串口UART42/COM42【移远会自动生成连续三个串口&#xff0c;最小的那一个】 AT命令&#xf…

C++(6):逻辑运算符

目录 1. 代码示例 示例 1&#xff1a;基础用法 示例 2&#xff1a;条件判断 2. 短路求值&#xff08;Short-Circuit Evaluation&#xff09; 代码示例 3. 实际应用场景 场景 1&#xff1a;输入合法性验证 场景 2&#xff1a;游戏状态判断 4. 注意事项 逻辑运算符用于组…

NXP iMX8MP ARM 平台多屏幕克隆显示测试

By Toradex秦海 1). 简介 NXP i.MX8MP ARM SoC 支持 3 路 Display Controller 分别提供 DSI/HDMI/LVDS 显示输出&#xff0c;在 Yocto Linux BSP 下采用 Wayland Backend 基于 DRM subsystem 显示驱动&#xff0c;前端默认基于 Weston Compositor。因此在默认情况下连接多个屏…

【数据结构】——栈

一、栈的概念和结构 栈其实就是一种特殊的顺序表&#xff0c;其只允许在一端进出&#xff0c;就是栈的数据的插入和删除只能在一端进行&#xff0c;进行数据的插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的元素遵循先进后出LIFO&#xff08;Last InFirst O…

Navicat中保存的数据库密码找回 Java 8

导出数据库连接打开导出的connections.ncx文件找到加密的password放入java程序中解密即可 package com.asia.card.cloud.enterprise.api;import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.cha…

vs code管理员权限启动问题

vs code非管理员启动可以正常启动用管理员启动vs code&#xff0c;会提示 解决办法 找到argv.json文件在argv.json文件中添加 "disable-chromium-sandbox": true重启vs code即可

Spring Cloud与Service Mesh集成:Istio服务网格实践

文章目录 引言一、Spring Cloud与Service Mesh概述二、Istio服务网格架构三、Spring Cloud与Istio集成的基础设施准备四、服务发现与负载均衡五、流量管理与弹性模式六、安全通信与认证授权七、可观测性集成八、配置管理集成总结 引言 微服务架构已成为现代分布式系统的主流设…

React+Taro选择日期组件封装

话不多说&#xff0c;直接上效果 1.页面渲染时间模块 {this.renderCalendarPopup()}2.引入时间组件弹层&#xff0c;state中加入showPopup(控制什么时候展示时间选择弹层)&#xff0c;time(选择后的时间值) private renderCalendarPopup () > {const { showPopup, time…

C++进阶--AVL树的实现续

文章目录 C进阶--AVL树的实现双旋AVL树的查找AVL树的检验结语 很高兴和搭大家见面&#xff0c;给生活加点impetus&#xff0c;开启今天的比编程之路&#xff01;&#xff01; 今天我们来完善AVL树的操作&#xff0c;为后续红黑树奠定基础&#xff01;&#xff01; 作者&#x…

AutoGen+Deepseek+chainlit的简单使用

AutoGen 的应用场景 AutoGen 作为一个强大的多智能体协作框架&#xff0c;可用于多种复杂任务&#xff1a; 自动化工作流&#xff1a;构建由多个智能体组成的流水线&#xff0c;例如数据收集、分析、报告生成复杂问题分解&#xff1a;将难题拆解为子任务&#xff0c;分配给不…

采用SqlSugarClient创建数据库实例引发的异步调用问题

基于SqlSugar编写的多个WebApi接口&#xff0c;项目初始化时采用单例模式注册SqlSugarClient实例对象&#xff0c;前端页面采用layui布局&#xff0c;并在一个按钮事件中通过Ajax连续调用多个WebApi接口获取数据。实际运行时点击按钮会随机报下面几种错误&#xff1a; Execute…

第7次课 栈A

课堂学习 栈&#xff08;stack&#xff09; 是一种遵循先入后出逻辑的线性数据结构。 我们可以将栈类比为桌面上的一摞盘子&#xff0c;如果想取出底部的盘子&#xff0c;则需要先将上面的盘子依次移走。我们将盘子替换为各种类型的元素&#xff08;如整数、字符、对象等&…

软考-软件设计师中级备考 13、刷题 数据结构

倒计时17天时间不多了&#xff0c;数据库、UML、等知识点有基础直接略过&#xff0c;法律全靠考前的一两天刷题&#xff0c;英语直接放弃。 一、数据结构&#xff1a;链表、栈、队列、数组、哈希表、树、图 1、关于链表操作&#xff0c;说法正确的是&#xff1a; A)新增一个头…

centos的根目录占了大量空间怎么办

问题 当根目录磁盘不够时&#xff0c;就必须删除无用的文件了 上面的&#xff0c;如果删除/usr 或/var是可以释放出系统盘的 定位占空间大的文件 经过命令&#xff0c;一层层查哪些是占磁盘的。 du -sh /* | sort -rh | head -n 10 最终排查&#xff0c;是有个系统日志占了20…

电子电器架构 --- 新能源高压上下电那点事一文通

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…