分布式事务解决方案(一) 2PC、3PC、TCC、Sega

news2024/9/8 23:12:43

目录

1.绪论

2.2PC

2.1 基本原理

2.1.1 组成

2.1.2 步骤

1.prepare阶段

2.commit阶段

2.2 2PC 存在的问题

2.2.1 阻塞问题

2.2.2 单点故障问题

1. 事务协调器宕机

2.部分数据不一致问题

2.资源管理器宕机

3. 事务协调器和资源管理管理器同时宕机

2.2 实现

2.2.1 XA规范

2.2.2 seata的AT模式

3.3PC

3.1 基本原理

3.1.1 canCommit阶段

3.1.2 prepareCommit阶段

3.1.3 commit阶段

3.2 3pc的优缺点

3.2.1 优点

3.2.2 缺点

4.TCC

4.1 基本原理

4.2 异常情况分析

4.2.1 confirm失败如何处理

4.2.2 允许空回滚

4.2.3 防悬挂控制

4.2.4 幂等性

4.3 TCC的优缺点

4.3.1 优点

4.3.3 缺点

5. sega模式

5.1 基本原理

5.2 补偿策略

5.2.1 逆向模式

5.2.2 正向模式

5.3 实现方式

5.3.1 命令协调

1.基本原理

2.优缺点

5.3.2 事件传播

1.基本原理

2.优缺点

6.总结

7.引用


1.绪论

在单体系统中,我们可以通过mysql的本地事务来保证操作的原子性,但是在分布式系统中,不同系统之间通过RPC进行远程调用,协作完成整体功能。这时,我们便需要分布式事务来保证操作的原子性。

2.2PC

2.1 基本原理

2.1.1 组成

要实现2pc主要有两部分组成,分别是事务协调器(TM),资源管理器RM。

事务协调器:事务协调器一般是一个独立的服务,主要用来生成全局事务ID,并且向资源管理器发送预写和提交请求。

资源管理器:资源管理器一般是一个sdk,我们需要实现分布式系统的服务需要依赖这个sdk。它主要是接受事务协调器的预写请求,并且代理业务系统对mysql的操作请求,完成本地事务的提交与回滚。

2.1.2 步骤

2pc主要分成两个阶段,分布式prepare阶段和commit阶段。

1.prepare阶段

步骤如下:

1.客户的发送请求到事务协调器;

2.事务协调器发送prepare请求给资源管理器;

3.资源管理器执行sql,并且记录undolog,但是此时并未commit;

4.如果资源管理器执行sql成功,便给事务协调器返回ack响应。

2.commit阶段

步骤如下:

1.在第一阶段的预提交过程中,如果事务收到所有资源管理器的预提交请求,并且开始对所有资源管理器发送commit;如果资源管理器返回失败或者超时,便对资源管理器发起rollback。

2.执行本地事务,commit或者rollback。

3.资源管理器向事务协调器返回commit结果。

4.资源管理器

2.2 2PC 存在的问题

2.2.1 阻塞问题

这时2pc最核心的问题,即由于2pc在第一阶段的时候只是执行事务操作,但是未commit事务,所以这个时候会占用资源。只有在整个分布式事务操作完成过后,资源才会被释放。

2.2.2 单点故障问题

1. 事务协调器宕机

假设在执行完prepare操作后,将资源锁定。协调者宕机,这些未commit的事务可能一直存在直到本地事务执行时间超过最大执行时间报错。对此,我们可以对资源协调器采用主备方式进行部署,如果主节点宕机,将从节点选为新的TM。当出现新的TM出现时,需要询问所有RM是否有在途的事务,并且完成后续操作。

2.部分数据不一致问题

在第一阶段提交数据过后,在第二阶段进行commit操作的时候,由于网络问题,部分RM执行commit成功,部分节点未收到commit操作,此时肯能导致部分节点数据不一致。

2.资源管理器宕机

prepare阶段宕机:prepare阶段宕机后,TM收不到RM的prepare的ack消息,会让所有的TM进行回滚。

commit阶段宕机:commit阶段宕机过后,其他rm已经执行了commit操作。这个时候TM可以进行重试,如果RM在重试期间恢复,不会导致数据不一致。

3. 事务协调器和资源管理管理器同时宕机

prepare阶段同时宕机:此时还未进行commit操作,新的TM可以通过其他RM获取的接下来应该执行commit或者rollback操作。

commit阶段同时宕机并且宕机时资源管理器未执行commit操作:此时TM可以询问所有RM,获取到当前事务的执行情况,该执行commit或者rollback(因为每个事务有个全局事务id,如果发送了commit请求,RM存有记录)。当宕机的TM恢复过后,执行当前事务操作即可。

可以看出,在TM和RM宕机的情况下,2pc都能保持数据一致性,但是这是建立在TM和RM至少有一个知道当前事务执行状态的请求的情况下,如果在commit阶段的时候,TM和全部RM宕机重启,没人知道当前事务是应该commit还是rollback。此时会导致数据不一致。

2.2 实现

2PC的实现主要有数据库的XA规范,seata的AT模式。

2.2.1 XA规范

XA就是X/Open DTP定义的交易中间件与数据库之间的接口规范,其接口函数有数据库厂商提供。只要数据库支持XA规范,便不需要引入额外的框架,利用该数据库原生的功能实现2PC。

2.2.2 seata的AT模式

seata的AT模式为了解决2pc的第一个问题,也即同步阻塞问题,在prepare阶段会直接进行commit(但是此时会在被修改记录加上行锁,防止其他客户端修改),但是此时会对修改数据加上行锁,防止并且在数据库中记录一条undo log日志,如果在commit阶段,需要回滚,可以根据undo log恢复到以前的数据。

3.3PC

3.1 基本原理

3pc和2pc的最主要的区别是,3pc在2pc的基础上增加了一个cnacommit阶段,降低了资源锁定的时间,另一个就是增加了超时机制,避免了前面说的事务管理器的单点故障问题。

可以看出3PC主要分为3个阶段:

3.1.1 canCommit阶段

1.协调器向管理器发送canCommit请求,询问资源管理器是否可以执行事务操作。

2.资源管理器根据自身情况判断是否可以执行事务操作,并且给协调器返回结果。

3.1.2 prepareCommit阶段

1.如果资源管理器在can commit阶段全部返回yes,协调器会向资源管理器发送prepare请求。

2.资源管理器开始执行事务,并且记录undolog日志,但是此时未commit。

3.执行完成给事务协调器返回ack。

4.如果事务协调器在直未收到资源管理器的ack请求,或者某个资源管理器返回了no,事务协调器发送absort请求,中断事务。

3.1.3 commit阶段

1.当事务协调器收到所有资源管理器的返回,并且都为yes时,向资源管理器发送commit请求。

2.当资源管理器收到commit请求后,commit本地事务。

3.向资源管理器返回ack。

4.如果有资源管理器返回commit失败,或者等待失败,事务协调器向资源管理器发送abort请求。资源管理器利用二阶段提交的undo log日志进行回滚。

3.2 3pc的优缺点

3.2.1 优点

1.增加了cancommit阶段,降低了锁资源的时间。

2.在事务协调器宕机过后,资源管理器会因为长时间未收到事务协调器的消息回滚,不会长时间阻塞资源。

3.2.2 缺点

和2pc一样,在docommit阶段,因为网络原因,资源管理器可能因为长时间未收到事务协调器的commit或者abort请求,导致各个资源协调器的数据不一致。

4.TCC

4.1 基本原理

TCC一般是由业务层实现,主要分为3个阶段,分别是try,confirm和catch。其中第一阶段为try接口实现的业务逻辑,这里一般为业务逻辑的具体实现。如果所有系统都try成功便执行confirm接口,如果某个系统try失败,便执行cancel接口。

可以看出步骤如下:

1.业务应用启动事务;

2.业务应用开始调用各个参与分布式事务的系统提供的try接口。比如库存服务,我们可以在try阶段预占库存,在confirm阶段才扣减库存。

3.如果每个系统都try成功,便执行confirm接口。

4.如果其中有系统try失败或者未收到业务系统对try操作的反馈,便执行cancel接口。

4.2 异常情况分析

4.2.1 confirm失败如何处理

二阶段提交都会存在confirm失败的情况,在前面2pc中,如果commit失败,可以利用prepare记录的undo log日志回滚。在tcc中,一般采用的是重试的方式。如果重试不成功,可以记录日志,认为干预。

4.2.2 允许空回滚

在tcc的第四步,在事务协调器等待业务系统try操作的反馈超时后,会执行cancel操作,但是此时,业务系统并没有收到try请求。

针对对上述问题,我们可以通过幂等性来保证,比如我们可以给每个事务加一个事务id,并且记录事务流水,在执行cancel操作前,我们可以根据事务id查询出当前事务是否执行过try操作,如果没有,便直接返回成功。

4.2.3 防悬挂控制

悬挂控制指的是,在事务协调器等待业务系统try操作的反馈超时后,会执行cancel操作,但是此时,业务系统并没有收到try请求。但是因为前面要求业务系统运行空回滚,所以事务协调器任务事务已经cancel成功。但是后面try请求又到达业务系统,此时应该禁止try操作执行。

解决办法和防止空回滚一样,也是通过事务id保证在执行完cancel操作的事务不会再执行try操作。

4.2.4 幂等性

因为tcc中会存在重试机制,或者网络抖动也可能导致事务重试,所以需要报保证实现tcc业务系统的幂等性。

4.3 TCC的优缺点

4.3.1 优点

1.锁资源的粒度交给业务系统实现,降低锁资源粒度。

2.利用重试机制保证最终一致性。

3.事务协调器也可以交给业务系统实现,避免单点故障。

4.3.3 缺点

业务方需要实现try,cancel, confirm三个接口,代码侵入性高。

5. sega模式

5.1 基本原理

sega模式其实也是二阶段提交。只是sega将一个分布式事务分成多个能够保证幂等性的子事务,并且依次向后提交,并且会给每个子事务保存一个补偿操作。在第一阶段提交的时候,便会直接提交事务。如果存在某个子事务执行失败,便会在第二阶段执行补偿操作。

5.2 补偿策略

sega模式有两种补偿策略,分别是正向模式和逆向模式。

5.2.1 逆向模式

逆向模式其实就是当某个子事务执行Ti执行失败,会按照执行顺序的反方向向后进行回滚。

5.2.2 正向模式

正向模式是当某个子事务执行失败后,会进行重试。这种适合于一定要成功的场景。

5.3 实现方式

5.3.1 命令协调

1.基本原理

其实就是单独的部署一个事务协调器,负责处理每个子事务的执行和回滚。

2.优缺点

优点:

1.服务之间关系简单。

2.业务系统实现简单,只需要接收事务协调器的命令并返回结果。

缺点:

1.事务协调器可能会有单点故障问题。

2.事务过多时,事务协调器可能压力过大。

5.3.2 事件传播

1.基本原理

比如现在分别有3个子事务,订单服务,库存服务,支付服务。订单服务执行完会发布本地事务执行完成的消息,库存服务和支付服务收到消息过后执行本地事务,并且发布消息并且被其他服务监听。

2.优缺点

优点:

1.没有事务协调器,所以没有单点故障的风险。

2.服务少时开发简单。

缺点:

1.可能存在循环依赖的风险。

2.服务多时,事务传播关系复杂。

6.总结

本文讲了,2PC、3PC、TCC、Sega这4中分布式事务的实现方式,它其实对应的就是seata的AT、XA、TCC和sega模式。上述四种方式都是2pc的变种,他们都支持事务执行失败或者成功。这是后文将要介绍的通过消息方式来保证最终一致性的方式的本质区别。

那他们分别适合于什么场景呢?

XA模式是标准的2PC,在第一阶段会锁定资源,在第二阶段才会进行提交,所以它的一致性是最强的,但是性能相对偏低。

AT是对2PC的优化,它在第一阶段便将数据已经提交,第二阶段如果commit失败,可以利用第一阶段保留在数据库中的undo log日志进行回滚。AT和XA一样,都会在数据库中留下undo log日志,所以只能支持Mysql这种关系型数据库的操作。

TCC的其实就是将预提交和提交操作交给业务系统实现,所以它可以在try操作中加入对redis或者es这种非关系型数据库的操作。但是它要求业务系统实现try,confirm,cancel这3个接口,所以相对复杂。

sega主要是针对长事务,比如调用多个第三方接口,或者外部系统的接口。适合采用sega模式,但是需要编写补偿代码(回滚或者重试)。

7.引用

[1]. 七种常见分布式事务详解

[2]. 分布式事务 Seata Saga 模式首秀以及三种模式详解

[3]. Seata的4种事务模式,各自适合的场景是什么?

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

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

相关文章

【AI落地应用实战】Amazon Bedrock +Amazon Step Functions实现链式提示(Prompt Chaining)

一、链式提示 Prompt Chaining架构 Prompt Chaining 是一种在生成式人工智能(如大型语言模型)中广泛使用的技术,它允许用户通过一系列精心设计的提示(Prompts)来引导模型生成更加精确、丰富且符合特定需求的内容。 P…

freertos-HAL库-STM32Cubemax生成

打开cubemax选好型号配置RCC(外部高速时钟)这里查看原理图,我们把按键设为输入,led设为输出创建两个新任务(default是系统创建的)配置时钟,这里HSE是外部高速时钟,HSI是内部的&#…

打卡第27天------贪心算法

再次祈祷上帝,提前预备好自己,希望我可以在机会来临的时候,抓住机会,成功上岸! 一、理论基础 什么是贪心?例如:有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿? 你肯定是每次拿最大的,最终结果就是拿走最大数额的钱了。 每次拿最大的就是局部最优,…

【Python从入门到进阶】61、Pandas中DataFrame对象的操作(二)

接上篇《60、Pandas中DataFrame对象的操作(一)》 上一篇我们讲解了DataFrame对象的简介、基本操作及数据清洗相关的内容。本篇我们来继续讲解DataFrame对象的统计分析、可视化以及数据导出与保存相关内容。 一、DataFrame的统计分析 在数据分析和处理中…

Selenium Java中的isDisplayed()方法

isDisplayed()方法用于确定元素是否可见。本文将详细讨论 的WebElement接口isDisplayed()方法。 方法声明- boolean isDisplayed()它能做什么?此方法用于判断元素是否显示。这个方法节省了我们…

EasyExcel入门

目录 一、文章简介 二、概念 1.EasyExcel是什么? 2.EasyExcel 能用在哪里? 3.为什么要选用EasyExcel解析excel? 4.如何使用EasyExcel? 三、EasyExcel快速入门 1.环境搭建 2.简单写excel 代码示例 TestFileUtil Employe…

C++(week14): C++提高:(二)C++11线程库

文章目录 一、线程1.C11线程库的概述2.构造函数3.线程启动: 线程入口函数的传递方式4.线程终止5.线程状态6.获取线程id:get_id() 二、互斥锁1.什么是互斥锁2.头文件3.常用函数接口 三、lockguard与unique_lock1.lock_guard2.unique_lock(1)概念(2)函数接口 3.原子数…

Python脚本:使用PyPDF2给一个PDF添加上页数/总页数标签

一、实现代码 import PyPDF2 from PyPDF2 import PdfWriter from PyPDF2.generic import AnnotationBuilder# 指定输入和输出pdf pdf_path rC:\Users\ASUS\Desktop\temp\xxxx.pdf out_path rC:\Users\ASUS\Desktop\temp\xxxx2.pdf# 创建 PdfWriter 对象 writer PdfWriter()…

Python转换Excel文件为SVG文件

SVG(Scalable Vector Graphics)是一种基于XML的矢量图像格式。这种格式在Web开发和其他图形应用中非常流行,提供了一种高效的方式来呈现复杂的矢量图形。如果我们需要在网页中嵌入Excel表格,或是直接使用Excel工作表制作网页&…

基于元神系统编写“清屏”程序

1. 背景 本文介绍了基于元神系统开发软件的操作流程,并详细介绍了“清空屏幕”程序的编写以及测试结果。 2. 方法 (1)编写程序 在元神系统0.4版的基础上,用FASM汇编语言进行软件开发。假设屏幕为80列25行的文本显示模式&#…

【更新2022】各省农业科技活动经费(RD)测算 1999-2022 无缺失

各省农业科技活动经费(R&D)测算数据在农业经济学、政策研究和农村发展规划等领域的论文研究中具有重要应用价值。首先,这些数据可以用于分析不同省份在农业科技投入上的差异及其对农业生产力和产出的影响,帮助揭示不同地区农业…

Node.js版本管理工具之NVM

目录 一、NVM介绍二、NVM的下载安装1、NVM下载2、卸载旧版Node.js3、安装 三、NVM配置及使用1、设置nvm镜像源2、安装Node.js3、卸载Node.js4、使用或切换Node.js版本5、设置全局安装路径和缓存路径 四、常用命令技术交流 博主介绍: 计算机科班人,全栈工…

坐牢十八天 20240729(IO)

一.笔记 1. 有关系统时间的函数 1> 有关时间的函数 #include <time.h> time_t time(time_t *tloc); 功能&#xff1a;获取系统时间&#xff0c;从1970年1月1日0时0分0秒&#xff0c;到目前累计的秒数 参数&#xff1a;用于接收的秒数 返回值&#xff1a;秒数使…

【每日刷题】Day89

【每日刷题】Day89 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 2. 155. 最小栈 - 力扣&#xff0…

Open3D 计算点云质心

目录 一、概述 1.1原理 1.2实现步骤 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSDN博客 一、概述 1.1原理 在Open3D中&am…

成为git砖家(8): 使用 git log 查询范围内的 commit

文章目录 1. 查询 git log 的文档2. 不带任何参数: git log 啥意思&#xff1f;3. git log 最主要功能是什么&#xff1f;4. git log <commit1>..<commit2> 什么意思5. 查看最近n次commit6. References 1. 查询 git log 的文档 git help log --web市面上针对 git …

从善如流之您最亲近人之善,肯出力之象-下学而上达

您最亲近人之善&#xff0c;肯出力之象&#xff0c;就是那个爬&#xff0c;甚至于跪倒在地上&#xff0c;抹那个下水井子。这或许就是那个马云大佬讲过的&#xff0c;就是从您最近距离&#xff0c;身边的人学习。人家为啥做的好&#xff0c;出色&#xff1f;而且您是一母同胞之…

太坑了!RabbitMQ+PHP开发的辛酸经历

博主介绍&#xff1a;全网粉丝10w、CSDN合伙人、华为云特邀云享专家&#xff0c;阿里云专家博主、星级博主&#xff0c;51cto明日之星&#xff0c;热爱技术和分享、专注于Java技术领域 &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅…

设计模式:模板方法模式:封装不变,扩展可变

目录 一、模板方法模式的定义与结构 二、模板方法模式的优点 三、模板方法模式的示例 示例一&#xff1a; 示例二&#xff1a; 四、总结 在软件开发中&#xff0c;设计模式是解决常见问题的可复用方案。其中&#xff0c;模板方法模式是一种行为型设计模式&#xff0c;它在不…