【Seata】03 - Seata AT 模式全局锁相关知识简单整理

news2025/1/12 3:54:20

文章目录

    • 前言
    • 参考目录
    • 版本说明
    • 分析整理
      • 1、全局锁的引入说明
      • 2、全局锁相关源码整理
      • 2.1、流程简图
      • 2.2、事务分支注册前的 SQL 相关操作
      • 2.3、注册分支(获取全局锁)

前言

上一篇文章介绍了 AT 模式的调用流程,但是有个比较重要的概念没有提及到,所以这一篇来展开说明一下——全局锁。

参考目录

  • Seata 官方文档
  • Seata 官方 Demo :seata-xa
  • Seata AT 模式

版本说明

由于官方 Demo 版本较低,本文使用的版本如下:

  • SeataV1.7.0
  • druid-spring-boot-starterV1.2.16

分析整理

1、全局锁的引入说明

在官方文档对于 AT 模型的篇章中有进行关于读写隔离的示例说明,这其中就涉及到了全局锁。

(截图自官方文档)在这里插入图片描述

在 Demo 里面业务主要是进行了写隔离,因此下面的分析也是以此为基础进行展开。

上图简明扼要提出了全局锁的获取时机以及应用场景,下面结合源码来看下。

2、全局锁相关源码整理

2.1、流程简图

上篇文章有根据输出记录按照时序步骤绘制了流程图,对关键的信息进行提取后加上全局锁的内容,绘制了新的流程图:

在这里插入图片描述

简单说明一下:

  • 这张简图主要是事务分支相关的操作,因此没有绘制 TM 相关的内容。
  • 虚线方框内是同一个方法的操作。
  • 主要的方法也一并贴出来方便后续查找。

2.2、事务分支注册前的 SQL 相关操作

这一部分在上一篇文章也有提及,这里再简单带过一下。

在分支注册前,回先执行业务逻辑,生成前后镜像,再贴一下堆栈信息图:

在这里插入图片描述

io.seata.rm.datasource.exec.AbstractDMLBaseExecutor#executeAutoCommitFalse

在这里插入图片描述

得到前后镜像是为了生成 UndoLog 方便后续回滚操作。SQL 执行之后还没有 Commit,需要获取到全局锁并且在数据库表中写入 UndoLog 后才会提交。

完成这一步骤之后,继续分支事务操作,方法 io.seata.rm.datasource.ConnectionProxy#processGlobalTransactionCommit 完成了三个重要步骤:

  1. 注册分支(包含获取全局锁)
  2. undo_log 记录插入
  3. SQL 提交

在这里插入图片描述

本文的分析要点集中在步骤 1 中,对于步骤 2 上一篇博客已经进行了详细的分析,也贴出了相关的 UndoLog 内容,本文就不再进行说明。

2.3、注册分支(获取全局锁)

来到 Client 端(RM)注册分支的底层方法:

io.seata.rm.AbstractResourceManager#branchRegister

在这里插入图片描述

来到 Server 端(TC)的分支注册方法:

io.seata.server.coordinator.AbstractCore#branchRegister

在这里插入图片描述

该方法的主要逻辑:

  1. 使用 xid 获取到全局会话。
  2. 锁定会话并在事务上下文进行操作。
  3. 全局会话状态检查。
  4. 全局会话添加会话生命周期监听器。
  5. 新建全局事务分支,获得分支会话对象。
  6. 锁定分支会话。
  7. 将分支会话添加到全局会话中,如果出现异常,解锁分支并抛出异常。
  8. 打印日志并返回分支id。

下面来看看底层是如何实现的:

branchSessionLock(globalSession, branchSession);

io.seata.server.transaction.at.ATCore#branchSessionLock

在这里插入图片描述

根据打印的日志记录来看,应用数据 applicationData 是 null,因此直接进入到子方法。

io.seata.server.session.BranchSession#lock

在这里插入图片描述

io.seata.server.lock.AbstractLockManager#acquireLock

在这里插入图片描述

这个方法会从分支会话中获取所有行锁信息。

// get locks of branch
List<RowLock> locks = collectRowLocks(branchSession);

io.seata.server.lock.AbstractLockManager#collectRowLocks

在这里插入图片描述

上图以其中一个事务分支为例对方法进行了简单的逻辑梳理。该方法根据分支注册请求信息构建了锁对象集合并返回。

顺便说一下,transactionId 实际上就是 xid 中 IP 端口后面的那一长串数字:

  • xid:192.168.2.117:8091:2252230319988862988
  • transactionId:2252230319988862988
  • branchId:2252230319988862990

在这里插入图片描述

回到上一层继续往下深入获取锁。

io.seata.server.storage.db.lock.DataBaseLocker#acquireLock

在这里插入图片描述

io.seata.server.storage.db.lock.LockStoreDataBaseDAO#acquireLock
在这里插入图片描述

这是获取全局锁的主要方法,方法逻辑如下:

  1. 首先,该方法获取数据库连接 conn,并设置自动提交属性为 false。同时,创建 PreparedStatement 对象 ps 和 ResultSet 对象 rs,以及一个用于存储已存在行键的 HashSet 集合 dbExistedRowKeys。

  2. 如果传入的锁对象列表 lockDOs 的大小大于1,则通过过滤去除重复的行键,将其赋值给 lockDOs。这样可以确保锁对象列表中不会存在重复的行键。

  3. 如果 skipCheckLock 参数为 false,说明需要进行锁的检查。即先查询数据库中的锁表,判断是否有其他事务正在持有或正在回滚相同的全局锁。

    • 创建一个查询检查锁的 SQL 语句 checkLockSQL,并将锁对象数量作为参数传递给该语句。
    • 通过 PreparedStatement 对象 ps 执行 checkLockSQL,并将锁对象的行键作为参数设置到 PreparedStatement 对象中。
    • 执行查询并遍历 ResultSet 对象 rs。对于每一行记录,检查是否存在其他事务持有相同的全局锁。
      • 如果存在其他事务持有相同的全局锁,则设置 canLock 标志为 false,并终止循环。
      • 同时,将查询到的数据库中已存在的行键添加到 dbExistedRowKeys 集合中。
    • 如果 canLock 标志为 false,表示无法获取锁,执行回滚操作,并根据 autoCommit 参数和锁的状态判断是否需要抛出异常。
    • 如果 dbExistedRowKeys 集合不为空,表示锁在数据库中已存在,因此需要将这些行键从 lockDOs 列表中移除。
  4. 如果经过锁的检查后,lockDOs 列表为空,表示锁已全部存在于数据库中,无需再次获取锁,直接提交事务并返回 true。

  5. 接下来,执行锁的获取操作。如果 lockDOs 列表中只有一个锁对象,调用 doAcquireLock 方法进行单个锁的获取。如果获取失败,执行回滚操作,并返回 false。

  6. 如果 lockDOs 列表中存在多个锁对象,调用 doAcquireLocks 方法进行批量锁的获取。如果获取失败,执行回滚操作,并返回 false。

  7. 最后,提交事务,关闭 ResultSet、PreparedStatement 对象,根据原始的自动提交属性设置连接的 autoCommit 属性,并关闭数据库连接。

io.seata.server.storage.db.lock.LockStoreDataBaseDAO#doAcquireLock
在这里插入图片描述

获取到全局锁后,会把锁信息保存到数据库表 lock_table 中,在释放锁后记录也会删除。

(完)

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

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

相关文章

【已解决】pycharm 突然每次点击都开新页面,关不掉怎么办?

今天在 pycharm 中写代码&#xff0c;突然发现&#xff0c;新开的文件不再原来的页面上&#xff0c;而是新增了页面&#xff0c;导致整个屏幕全都是新开的页面&#xff0c;最难受的是&#xff0c;关不掉&#xff01; 无奈&#xff0c;我只能关闭 pycharm&#xff0c;重新双击…

nginx-带宽限制-令牌桶算法

nginx的令牌桶算法 客户请求nginx时&#xff0c;通过给每个请求授予令牌&#xff0c;来给予每个请求响应的带宽&#xff0c;当令牌全部授予完了&#xff0c;后面的请求就处于等待中。 假如一个令牌给100M带宽&#xff0c;那么两个令牌就是200M。有多少牌子&#xff0c;就有多少…

附导读 |《网络安全标准实践指南——网络数据安全风险评估实施指引》解读

★ NEWS ★ 2023年4月18日&#xff0c;全国信息安全标准化技术委员会秘书处发布《网络安全标准实践指南——网络数据安全风险评估实施指引&#xff08;征求意见稿&#xff09;》&#xff08;以下称“《实施指引》”&#xff09;&#xff0c;面向社会公开征求意见。意见征求截…

C#,《小白学程序》第十五课:随机数(Random)第二,统计学初步,数据统计的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十五课&#xff1a;随机数&#xff08;Random&#xff09;第二&#xff0c;统计学初步&#xff0c;数据统计的计算方法与代码 /// 用随机数做简单的统计并用图形显示统计结果。 /// </summary> /// <param name&q…

<九> objectARX开发:读写Excel、json与txt格式文件

一、功能描述 在实际应用中,有时候我们需要通过文本格式或者表格等格式来传递数据,例如*.txt、Excel表格或者*.json文件。此时我们就需要想办法来读写这些数据。本节我们来说一下如何读写读写Excel、json与txt格式文件。 二、不同文件格式读写 2.1 读写Excel excel文件的读…

Python Opencv实践 - 图像的距(Moments,Hu Moments)

参考资料&#xff1a;​​​​​​矩特征---OpenCV-Python开发指南&#xff08;25&#xff09;_cv2.moments_李元静的博客-CSDN博客 探究opencv中的moments函数和HuMoments函数_opencv moment_傲笑风的博客-CSDN博客 import cv2 as cv import numpy as np import matplotlib.…

个人能做股票期权吗?个人期权交易开户条件新规

个人投资者是可以交易股票期权的&#xff0c;不过期权交易通常需要投资者具备一定的投资经验和风险承受能力&#xff0c;因为期权交易涉及较高的风险和复杂性&#xff0c;下文为大家介绍个人能做股票期权吗&#xff1f;个人期权交易开户条件新规的内容。本文来自&#xff1a;期…

LeetCode刷题笔记【26】:贪心算法专题-4(柠檬水找零、根据身高重建队列、用最少数量的箭引爆气球)

文章目录 前置知识860.柠檬水找零题目描述解题思路代码 406.根据身高重建队列题目描述解题思路代码 452. 用最少数量的箭引爆气球题目描述踩坑-进行模拟正确思路的贪心 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【23】&#xff1a;贪心算法专题-1&#x…

【DockerCE】Docker-CE 24.0.6正式版发布

官网下载地址&#xff08;For RHEL/CentOS 7.9&#xff09;&#xff1a; https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ 相对于24.0.5版本&#xff0c;本次24.0.6版本更新的rpm包有 5 个&#xff0c;使用目录对比软件对比的结果如下&#xff1a; 在Lin…

Rabbitmq 常见问题处理

Rabbitmq queue NaN status code 如下图&#xff1a; 参考文章 ## https://groups.google.com/g/rabbitmq-users/c/4MlYbOXvy4E## https://groups.google.com/g/rabbitmq-users/c/SsXtN165_30### https://www.cnblogs.com/weschen/p/13321817.html### https://community.piv…

Ubuntu终端指令

目录 一、基本指令 1.命令行提示符 2.切换用户 3.修改密码 4.查看当前目录下的文件 5.修改文件权限---chmod 6.cd 切换路径 7.touch 8.cat 9.echo 10.mkdir 11. rm/rmdir 二、在线下载软件 1.更新软件源 2.更新软件列表 3.下载软件 三、离线安装软件 1. 软件安装…

ES-OAS-ERP-电子政务-企业信息化

ES-OAS-ERP-电子政务-企业信息化 专家系统ES办公自动化系统OAS企业资源规划ERP典型的信息系统架构模型 专家系统ES 模拟人类专家&#xff0c;解决结构化&#xff0c;半结构化问题 数据级&#xff0c;知识库级&#xff0c;控制级 专家系统的特点就是和人的区别 启发性知识&#…

citavi合并重复文献题录

文章目录 一、宏macro的使用方法二、合并重复题录的macro代码2.1 下载并加载macro代码2.2 显示重复题录并合并2.3 合并的规则2.4 其他 附&#xff1a;macro代码 一、宏macro的使用方法 参考官方文档 Using macros - Citavi 6 Manual Macro files have the .cs file extension…

Echarts 柱状图逐条加载动画

展示效果: 相关代码: let xAxisData = []; const data1=[]; const data2=[]; const year = [2000

dll修复精灵,dll修复工具下载方法分享,mfc140u.dll缺失损坏一键修复

今天&#xff0c;我将为大家分享一个关于mfc140u.dll的问题。首先&#xff0c;我想问一下在座的网友们&#xff0c;有多少人知道mfc140u.dll是什么&#xff1f;又有多少人知道它的作用以及如何解决这个问题呢&#xff1f;在接下来的演讲中&#xff0c;我将详细介绍mfc140u.dll的…

炫我科技成功为乐歌提供渲染私有云系统解决方案

炫我科技于2023年8月25日成功交付乐歌渲染私有云系统项目。 “乐歌”为乐歌人体工学科技股份有限公司 品牌名。致力于以机、电、软一体化的线性驱动为核心&#xff0c;打造创新家居生活与办公方式&#xff0c;为全球用户提供健康、舒适、安全、高效的整体智能解决方案。主营产…

黑客利用 MinIO 存储系统漏洞危害服务器

据观察&#xff0c;未知威胁行为者利用 MinIO 高性能对象存储系统中的高严重性安全漏洞进行武器化&#xff0c;以在受影响的服务器上实现未经授权的代码执行。 国际知名白帽黑客、东方联盟创始人郭盛华表示&#xff0c;此次入侵利用了公开可用的漏洞利用链对 MinIO 实例进行后…

网络技术三:局域网基本原理

局域网基本原理 使用的协议及线缆 物理层 双绞线 同轴电缆 光纤 无线电 数据链路层 以太网 唯一事实标准 令牌环 淘汰 FDDI 光纤分布式接口 网络层 IP 唯一的事实标准 IPX 淘汰 Apple talk 淘汰 局域网设备 集线器 内部为总线型拓扑 任意时间只能由一台主机占用总线&a…

upload-labs 16/17关

16 将gif文件和包含一句话木马的php文件放在同一目录下&#xff0c;用cmd的copy命令将php文件整合进文件中。 可以看到最后一行包含了注入代码 将b1文件上传到服务器后&#xff0c;发现并未能正常执行代码&#xff0c;将上传后的文件下载到本地&#xff0c;打开后发现最后的代…

Unity的GPUSkinning进一步介绍

大家好&#xff0c;我是阿赵。   在几年前&#xff0c;我曾经写过一篇介绍GPUSkinning的文章&#xff0c;这么多年之后&#xff0c;还是看到不停有朋友在翻看这篇旧文章。今天上去GitHub看了一下&#xff0c;GPUSkinning这个开源的插件已经很久没有更新过了&#xff0c;还是停…