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

Seata服务端同步提交事务核心源码解析

文章目录

  • 前言
  • 一、doGlobalCommit(同步提交)
    • 2.1、closeAndClean()
    • 2.2、changeGlobalStatus
    • 2.3、doGlobalCommit
      • 2.3.1、findGlobalSession
  • 总结


前言

  本篇介绍Seata服务端TC如何驱动RM提交事务。


一、doGlobalCommit(同步提交)

  doGlobalCommit是提交事务的方法:
在这里插入图片描述
  首先会根据客户端传递的XID,查找是否存在全局事务,如果不存在,就直接返回客户端Finished,同样地,如果超时,直接返回给客户端TimeoutRollbacking
在这里插入图片描述
  添加一个监听器,然后利用SessionManager执行lambda表达式中的逻辑:

  • 如果全局事务的状态非Begin,直接返回false。
  • 如果全局事务的状态Begin
    • 关闭事务,释放全局锁
    • 驱动所有的RM提交事务,还要考虑到支持异步提交的场景。
      在这里插入图片描述

2.1、closeAndClean()

  closeAndClean的作用是释放全局锁,如果是AT模式,还需要执行clean的方法:
在这里插入图片描述
在这里插入图片描述
选择数据库的实现

  最终会释放锁 删除lock_table的记录:
在这里插入图片描述
在这里插入图片描述
  根据客户端发送的XID删除,最终会执行如下的SQL:

delete from lock_table where xid = ? ;

2.2、changeGlobalStatus

  同步提交的情况下:
在这里插入图片描述
  最终会走到DataBaseTransactionStoreManagerwriteSessionupdate分支:
在这里插入图片描述

在这里插入图片描述
  **执行如下的sql,更新global_table 的状态为2 **

update global_table set status = ?,gmt_modified = now() where xid = ?;

  commit在同步提交的情况下,会走到doGlobalCommit分支:
在这里插入图片描述

2.3、doGlobalCommit

  在doGlobalCommit方法中,首先会判断,如果当前的模式是SAGA,则走SAGA的这一部分逻辑。否则就是其他模式的提交
在这里插入图片描述
  首先会执行globalSession.getSortedBranches()方法,获取所有的分支事务信息:
在这里插入图片描述
  转换了一下源码中的写法,更加清晰易懂一点。
在这里插入图片描述

2.3.1、findGlobalSession

  最终会调用到DataBaseTransactionStoreManagerreadSession
在这里插入图片描述
  底层实际上是执行了两条SQL:

-- 查询的是global_table 表中所有的字段,简化成了*
select * from global_table where xid = ?";
-- 查询分支事务表,查出某个主线事务下的所有分支事务
select * from branch_table where xid = 上一条sql查询结果中的xid(主线事务的XID) order by gmt_create asc

  最终将当前主线事务下的分支事务,加到branchSessions集合中:

在这里插入图片描述

  在最外层SessionHelper#forEach中,会去遍历所有的分支事务,
在这里插入图片描述
  得到当前XID下的所有分支事务后,遍历所有的分支事务,执行lambda表达式中的内容
  如果分支在第一阶段就失败了,说明这个分支没有成功参与事务,因此可以将其从全局事务中移除,并继续下一个。PhaseOne_Failed的状态,是TC 已记录了这个分支(即注册成功),但分支主动上报自己第一阶段失败的结果,如果是因为RM业务发生了异常,则Spring 事务机制自动回滚,Seata 也不会写 undo log,也不会向 TC 汇报任何分支

  在branchCommit方法中,TC会驱动每一个RM去提交事务,然后根据RM返回的状态去判断

在这里插入图片描述

  • 如果返回的是PhaseTwo_Committed两阶段提交成功,则执行removeBranch,主要是删除该分支在lock_table的记录,并且删除branch_table的记录,清理branchSessions

在这里插入图片描述

  • 如果返回的是PhaseTwo_CommitFailed_Unretryable两阶段提交失败并且无法重试,则将整个全局事务标记为提交失败(Finished + 状态为 CommitFailed),并将其从内存事务会话中清理掉。

在这里插入图片描述

  最后会进行全局事务的最终处理,删除全局事务信息。
在这里插入图片描述

总结

  Seata 服务端在同步提交全局事务的过程中,主要完成了以下工作:

  • 释放锁,删除lock_table的记录。
  • global_table表中的状态改为2。
  • 遍历并驱动所有的分支事务提交(Phase Two 提交),每个分支由 TC 向对应的 RM 发起提交请求。
  • 根据各分支事务返回的状态进行处理:
    • 若分支返回 PhaseTwo_Committed,表示该分支已成功提交,TC 会调用 removeBranch 方法:清理内存中的 branchSession,并删除该分支在 branch_tablelock_table 中的记录。
    • 若分支返回 PhaseTwo_CommitFailed_Unretryable,表示分支提交失败且不可重试,TC 会将全局事务状态设置为 CommitFailed(属于结束状态),并清理内存中的全局事务会话。
  • 所有分支提交完成后,TC 会将 global_table 中该全局事务的状态更新为 Committed(提交成功)或 CommitFailed(提交失败)。
  • 如果全局事务已完成且所有资源已释放,TC 会清理 global_table 中对应事务的记录,以完成整个分布式事务的生命周期管理。
http://www.xdnf.cn/news/242911.html

相关文章:

  • MySQL零基础入门:Ubuntu环境安装与操作精解
  • 深度探索DeepSeek:从架构设计到性能优化的实战指南
  • WPF嵌入webapi服务器,充当微服务角色
  • ActiveMQ 性能优化与网络配置实战(二)
  • 使用Python和Pandas实现的Snowflake权限检查与SQL生成用于IT审计
  • 利用无事务方式插入数据库解决并发插入问题
  • windows系统搭建自己的ftp服务器,保姆级教程(用户验证+无验证)
  • OkHttp3.X 工具类封装:链式调用,支持HTTPS、重试、文件上传【内含常用设计模式设计示例】
  • 深度学习基础--目标检测入门简介
  • PHP之CURL通过header传参数及接收
  • day12:遗传算法及常见优化算法分享
  • 指针与算法的双人舞:蓝桥杯两道趣味题的降维打击
  • Windows 查看电脑是否插拔过U盘
  • 【业务领域】电脑主板芯片电路结构
  • 【音视频】ffplay数据结构分析
  • C++中常用的十大排序方法之1——冒泡排序
  • 内存安全的攻防战:工具链与语言特性的协同突围
  • SIEMENS PLC程序代码 赋值 + 判断
  • 数值求解Eikonal方程的方法及开源实现
  • 25.4.30数据结构|并查集 路径压缩
  • 《汉诺塔问题的C语言实现》
  • 第十一届蓝桥杯 2020 C/C++组 既约分数
  • RocketMQ常见面试题一
  • 25_04_30Linux架构篇、第1章_02源码编译安装Apache HTTP Server 最新稳定版本是 2.4.62
  • 若依 FastAPI + Vue3 项目 Docker 部署笔记( 启动器打包教程)
  • 华为云Astro大屏连接器创建操作实例:抽取物联网iotda影子设备数据的连接器创建
  • (B题|矿山数据处理问题)2025年第二十二届五一数学建模竞赛(五一杯/五一赛)解题思路|完整代码论文集合
  • 【音频】Qt6实现MP3播放器
  • 深入自制操作系统(一、Bootloader的实现)
  • 微软与Meta大幅增加人工智能基础设施投入