seata分布式事务原理_又见分布式事务之Seata
前言
分布式微服务中事务问题,是一直困扰着大家的。之前老顾已经介绍过如何利用rocketmq的事务消息解决事务问题,今天老顾再来介绍另一个方案;提供小伙伴们另一个选择。
解决方案有哪些?
分布式事务方案大致分为对业务无侵入型和有侵入型。
无侵入型的方案有基于数据库的XA协议的两阶段提交,它的优点对业务无侵入,缺点也很明显;数据库必须支持XA协议,且支持XA协议对性能的影响很大,因为它会造成事务资源长时间得不到释放。数据库的吞吐量极低。
为了解决这个问题,就出来了很多业务层面的实现二阶段的提交方案,如:很出名的 TCC 方案,基于 TCC 也有很多成熟的框架,如 ByteTCC、tcc-transaction。
另一种就是最终一致性的方案,如:rocketmq事务消息。
但上面的TCC方案、或者最终一致性方案都会涉及到业务代码的改造,对业务有侵入。
下面我们来介绍一下今天的主角。
Seata
Seata的分布式事务解决方案是业务层面的解决方案,业务层上无需关心分布式事务机制的约束,它将给我们的微服务架构带来质的提升,只依赖于单台数据库的事务能力。
Seata 的设计思路是将一个分布式事务可以理解成一个全局事务,下面挂了若干个分支事务,而一个分支事务是一个满足 ACID 的本地事务,因此我们可以操作分布式事务像操作本地事务一样。
Seata 内部定义了 3个模块来处理全局事务和分支事务的关系和处理过程,这三个组件分别是:
1、Transaction Coordinator (TC):事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
2、Transaction Manager (TM):控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
3、Resource Manager (RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。
其中,TM是一个分布式事务的发起者和终结者,TC负责维护分布式事务的运行状态,而RM则负责本地事务的运行。如下图所示:
下面是一个分布式事务在Seata中的执行流程:
1)TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。
2)XID 在微服务调用链路的上下文中传播。
3)RM 向 TC 注册分支事务,接着执行这个分支事务并提交(重点:RM在第一阶段就已经执行了本地事务的提交/回滚),最后将执行结果汇报给TC。
4)TM 根据 TC 中所有的分支事务的执行情况,发起全局提交或回滚决议。
5)TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。
分支事务为什么能直接提交?
Seata能够在第一阶段直接提交事务,是因为Seata框架为每一个RM维护了一张UNDO_LOG表(这张表需要客户端自行创建),其中保存了每一次本地事务的回滚数据。因此,二阶段的回滚并不依赖于本地数据库事务的回滚,而是RM直接读取这张UNDO_LOG表,并将数据库中的数据更新为UNDO_LOG中存储的历史数据。
如果第二阶段是提交命令,那么RM事实上并不会对数据进行提交(因为一阶段已经提交了),而实发起一个异步请求删除UNDO_LOG中关于本事务的记录。
原理就是先保存之前的老数据,一旦出现异常,就是把老数据再更新回去。
Seata执行流程
下面是一个Seata中一个分布式事务执行的详细过程:
1)首先TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。
2)XID 在微服务调用链路的上下文中传播。
3)RM 开始执行这个分支事务,RM首先解析这条SQL语句,生成对应的UNDO_LOG记录。下面是一条UNDO_LOG中的记录:
{ "branchId": 641789253, "undoItems": [{ "afterImage": { "rows": [{ "fields": [{ "name": "id", "type": 4, "value": 1 }, { "name": "name", "type": 12, "value": "GTS" }, { "name": "since", "type": 12, "value": "2014" }] }], "tableName": "product" }, "beforeImage": { "rows": [{ "fields": [{ "name": "id", "type": 4, "value": 1 }, { "name": "name", "type": 12, "value": "TXC" }, { "name": "since", "type": 12, "value": "2014" }] }], "tableName": "product" }, "sqlType": "UPDATE" }], "xid": "xid:xxx"}
可以看到,UNDO_LOG表中记录了分支ID,全局事务ID,以及事务执行的redo和undo数据以供二阶段恢复。
4)RM在同一个本地事务中执行业务SQL和UNDO_LOG数据的插入。在提交这个本地事务前,RM会向TC申请关于这条记录的全局锁。如果申请不到,则说明有其他事务也在对这条记录进行操作,因此它会在一段时间内重试,重试失败则回滚本地事务,并向TC汇报本地事务执行失败。如下图所示:
5)RM在事务提交前,申请到了相关记录的全局锁,因此直接提交本地事务,并向TC汇报本地事务执行成功。此时全局锁并没有释放,全局锁的释放取决于二阶段是提交命令还是回滚命令。
6)TC根据所有的分支事务执行结果,向RM下发提交或回滚命令。
7)RM如果收到TC的提交命令,首先立即释放相关记录的全局锁,然后把提交请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。异步队列中的提交请求真正执行时,只是删除相应UNDO LOG 记录而已。
8)RM如果收到TC的回滚命令,则会开启一个本地事务,通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。将 UNDO LOG 中的后镜与当前数据进行比较:
如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理。
否则,根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句并执行,然后提交本地事务达到回滚的目的。
最后释放相关记录的全局锁。
方案补充
上面的方案是Seata的默认模式,称为AT模式,它是类似于 XA 方案的两段式提交方案,并且是对业务无侵入,但是这种机制依然是需要依赖数据库本地事务的 ACID 特性。
小伙伴们有没有发现,整个流程的基础必须是支持 ACID 特性的关系型数据库,那么问题就来了,非关系型或者不支持 ACID 的数据库就无法使用 Seata 了?
Seata 现阶段为我们准备了另外一种模式,叫 MT 模式,它是一种对业务有入侵的方案,提交回滚等操作需要我们自行定义,业务逻辑需要被分解为 Prepare/Commit/Rollback 3 部分,形成一个 MT 分支,加入全局事务,其本质就是TCC方案。
不过MT模式,它不是 Seata “主打”的模式,它的存在仅仅作为补充的方案,从以上官方的发展远景就可以看出来,Seata 的目标是始终是对业务无入侵的方案。
总结
今天老顾介绍seata整体原理,以及执行流程,希望小伙伴们能够在原理本质上去先了解一下seata,后面的文章老顾会介绍一下项目实战,谢谢!!!
是兄弟,就来“kan”我
seata分布式事务原理_又见分布式事务之Seata相关推荐
- seata xid是什么_微服务分布式事务解决方案-springboot整合分布式seata1.3.0
概述 Seat是蚂蚁金服和阿里巴巴联合推出的一个开源的分布式事务框架,在阿里云商用的叫做GTS. 项目地址:https://github.com/longxiaonan/springcloud-dem ...
- 同事操作两个数据源保持事务一致_微服务分布式事务4种解决方案实战
分布式事务 分布式事务是指事务的参与者,支持事务的服务器,资源服务器分别位于分布式系统的不同节点之上,通常一个分布式 事物中会涉及到对多个数据源或业务系统的操作. 典型的分布式事务场景:跨银行转操作就 ...
- springcloud分布式事务解决方案_搞懂分布式技术18:分布式事务常用解决方案
本文转载自 http://linkedkeeper.com 本文内容参考网络,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 http ...
- spring手动控制事务开启_“上帝视角”图解Spring事务的传播机制原理
转载:https://mp.weixin.qq.com/s/odP1DKgRtXsCcAKxwGahug 数据库事务的"抓手" 数据库的事务功能已经由数据库自身实现,它留给用户的就 ...
- 不同类的方法 事务问题_深入理解 Spring 事务原理
Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...
- mysql数据库执行事务日志_第十章 MySQL事务及其日志介绍
一.数据库升级 #1.提出方案 1)升级的方法 2)升级的步骤 3)升级的时间 4)升级步骤可能会出现的问题 5)出现的问题怎么解决,解决时间 6)升级后出现的问题 #2.搭建新的数据库 #3.备份就 ...
- mysql读会产生事务吗_来谈谈MySQL事务及事务引发的问题
说起事务,肯定能够想到这样一句话,这个事情要么不做,要么做完:或者是好兄弟不求同年同月同日生,但求同年同月同日死.有点过分,但是是这个理儿. 四大特性 我们都知道,提到事务,就不能不提事务的四大特性, ...
- mysql如何查看事务日记_详解 Mysql 事务和Mysql 日志
事务特性 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破 ...
- ceph存储原理_热门的分布式存储系统ceph入门介绍
一.什么是ceph ceph是当前最热门的分布式存储系统之一,是软件定义存储(SDS,SoftwareDefinedStorage)解决方案中的典范.其具备良好的可靠性.可扩展性,应用范围包括块存储( ...
最新文章
- DL练习1:基于boston_house_prices的BP神经网络
- 字节跳动学习笔记:java多线程实现原理
- 产品经验谈:设计思维 统计思维
- 允许同站跨域Nginx配置方案
- Probe:Android线上OOM问题定位组件
- 【linux】make出现遗漏分隔符
- C# XML文件读取
- 数据层处理和性能优化
- 剑指offer 面试26题
- libiconv_百度百科
- Win32屏幕保护程序
- Unity Hex与Color之间进行颜色转换
- Element 之loading颜色修改
- JavaScript学习笔记01——简介(李炎恢JavaScript教程)
- python作业——SVM预测交通流量
- drop、delete、truncate比较
- Caffe Scale层
- Javascript轻应用命令行工具
- 2021下半年教资综合素质——主观题
- wordpress模板_如何在WordPress中添加漂亮的电子邮件模板
热门文章
- 三维坐标 偏转_三维坐标变换原理-平移, 旋转, 缩放
- springboot中mongodb自定义类型转换器
- java mcv_Spring和SpringMCV配置
- java扫描一个端口状态_java扫描端口,如何判断端口是用来做什么的(提供什么服务的)?...
- 控制只读_用Python控制硬件44-四位半万用表UT61E
- html做app的切换效果,Vue-router结合transition实现app动画切换效果实例分享
- java 类型转换原理_9.java数据类型的转换
- Linux系统文件夹权限475,linux系统中文件的特殊权限
- 2评分标准多少分_突发!财政部刚刚通知!2020年中级考试题目分值及评分标准大变!...
- mysql 修改字段长度_面试官:InnoDB记录存储结构都不知道,你敢说你懂MySQL?