当前位置: 首页 > 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 中对应事务的记录,以完成整个分布式事务的生命周期管理。

相关文章:

  • 【音频】基础知识
  • AI数字人系统开发:技术架构、应用场景与未来趋势
  • 西式烹饪实训室建设路径
  • 图论---有向图的强连通分量(Tarjan求SCC)
  • 内存安全的攻防战:工具链与语言特性的协同突围
  • 【docker学习笔记】如何删除镜像启动默认命令
  • Spring AI开发跃迁指南(第二章:急速上手3——Advisor核心原理、源码讲解及使用实例)
  • 多线程系列二:Thread类
  • 安装linux下的idea
  • Git 基本操作(一)
  • ARM ASM
  • watch 数组 Vue 3
  • 【AI提示词】决策树专家
  • 【Linux网络】I/O多路转接技术 - poll
  • Dagster资产工厂实战:从Python到YAML配置的高效ETL流程
  • 面试手撕——迭代法中序遍历二叉树
  • Python 装饰器基础知识科普
  • 【嵌入式———通用定时器基本操作——实验需求2:案列:测量PWM的频率/周期】
  • 【二】数字图像处理基础(上)【数字图像处理】
  • Linux日常使用与运维的AI工具全景调研:效率革命的终极指南
  • 净海护渔,中国海警局直属第一局开展伏季休渔普法宣传活动
  • 《探秘海昏侯国》数字沉浸特展亮相首届江西文化旅游产业博览交易会
  • 解放日报:“北斗七星”列阵,AI群星闪耀
  • 《求是》杂志发表习近平总书记重要文章《激励新时代青年在中国式现代化建设中挺膺担当》
  • 剪纸纹样“流动”在水乡,谁不忆江南
  • 商务部:已有超1.2亿人次享受到以旧换新补贴优惠