如果你还不知道SAGA,那这篇不容错过!|分布式事务系列(五)

news2024/10/7 13:17:28

这是分布式事务系列的第五篇,如果之前文章没读请自行前往。精华专题,强烈建议收藏。

‍本文详细讲解了分布式事务解决方案——SAGA。

点击上方“后端开发技术”,选择“设为星标” ,优质资源及时送达

SAGA事务

什么是SAGA事务

SAGA 的意思是“长篇故事、长篇记叙、一长串事件”。SAGA 事务模式的提出非常早,甚至早于分布式事务概念的提出。

SAGA 于 1987 年由普林斯顿大学的 Hector Garcia-Molina 和 Kenneth Salem 在 ACM 发表的论文《SAGAS》中提出。

6852a96752eb1b40d240e7d14049d77c.png

这篇论文讲述的核心是如何处理长时间活跃的事务,SAGA 指出可将其拆分成可以交错运行的子事务集合,每个子事务都是一个真实的事务,子事务可以独自保证数据一致性。

为什么需要SAGA

之前我们介绍了 TCC 分布式事务解决方案,它拥有诸多优点:更强的一致性、更强的个理性、更好的性能,但是他也有一个显著的缺点就是业务侵入性强。业务侵入性强并不只是说我们编码麻烦而已,有时候业务不是你想侵入就侵入的,比如其他部门不愿意配合,比如使用三方系统。

依旧是以我们熟悉的电商业务为例子,需要经过下单、余额支付、库存扣件这三个过程,之前我们已经用TCC实现了这个过程。假设现在新增一个业务场景,余额支付需要替换为直接使用绑定的银行卡付款,现在又怎么做?银行并不像是我们的自有系统一样,可以提供专门的接口供我们去将本次事务所需的资源占用、资源提交、以及资源回滚。

如果不能用TCC,怎么办?这种情况下,SAGA 就有了用武之地。

SAGA 内容

SAGA 基本协议内容如下:

  • 每个 SAGA 事务都由一系列的有序子事务(sub-transaction) T1,T2,…,Ti,…,Tn组成,每个事务都支持幂等。

  • 每个 Ti 都有对应的补偿动作Ci,比如 C1,C2,…,Ci,…,Cn,补偿动作用于撤销 T1,T2,…,Ti,…,Tn造成的影响。同样,补偿操作也需要支持幂等。

2f2ac45c4591788da4ca75dfdd3654ea.png

如果 T1 到 Tn 均成功提交,那么事务就顺利完成。只有有一个环节出现失败就要采取恢复策略。

恢复策略分为向前恢复和向后恢复两种,具体使用那种方案需要根据实际场景选择。

向前恢复(Forward Recovery)

如果某个环节的Ti事务提交失败,那么就对这个 Ti 事务不断进行重试(接口要幂等),直到接口返回成功。

正向恢复不需要对应的补偿动作Ci,适用于在业务上都为正向操作的场景。继续以电商为例,如果用户的订单付款成功,那就一定要发货。

顺序为 T1、T2、T3 (失败,不断尝试,继续执行)、T4……

如下图:

3d7a5710c5f05d6a58d1f44b8b535e5f.png

向后恢复(Backward Recovery)

如果某个环节的Ti事务提交失败,那么就执行这个 Ti 事务对应的补偿Ci操作,不断进行重试(Ci接口要幂等),直到接口返回成功。

这里要求 Ci 必须可以执行成功,适用于在业务上允许失败的场景。继续以电商为例,如果用户的订单支付失败,那么需要支付、订单和库存都执行补偿。

顺序为 T1、T2、T3(失败)、C3、C2、C1

如下图:

c958f69a90598db53b42dcd1e5a8d6b6.png

实现SAGA

实现SAGA注意事项

如果实现SAGA,有三个需要注意的点:

  1. Ti和Ci是幂等的,因为都需要重试以保证最终一致性。

  2. Ci 必须是能够成功的,否则SAGA将无法撤销影响,如果无法成功则需要人工介入做补偿。

  3. Ti 和Ci的执行顺序可以交换,不保证Ti一定在Ci前执行,但是最终执行效果相同,即子事务Ti影响被撤销。

这里着重说一下第三点,为什么要求Ci可以在Ti之前执行?因为网络之间的不稳定性,无法保证Ti一定执行,或者一定在Ci之前执行。具体来说,有以下三种执行情况。

  1. 正常情况:Ti先执行,Ci后执行。

  2. Ti请求因为网络问题丢失了,彻底不会执行。

  3. Ti执行超时,判断为执行失败,直到Ci执行前 Ti 都没有执行完成,导致出现Ci先执行的情况。

所以,有了第三点的要求,Ti 和 Ci 顺序可交换。

两种模式

通过阅读SAGA协议的具体内容,我们可以发现,实现的关键之一子事务之间的协调。首先我们要知道一个事务的开始,并且可以让子事务按顺序执行,并且在某个事务执行完后通知下一个子事务。如果有子事务执行失败,需要按照顺序执行补偿逻辑。

所以根据协调子事务的方法,可以分为两类:命令协调模式和事件编排模式。

  • 编排(Choreography):

  • 控制(Orchestration):

命令协调模式(Orchestration)

命令协调模式:由中央协调器集中处理事件的决策和业务逻辑排序,以命令或者回复的方式与每个参与服务进行通信,全权负责告诉每个参与者什么时候该做什么。

a5a306ad8ea45c672a76de46e54d7bd0.png

依旧以之前的电商为例:

  1. 事务发起者调用SAGA控制器开启事务(这里的控制器也可以由发起者兼任)。

  2. SAGA中央协调器发起扣减库存,库存扣减结果返回。

  3. SAGA中央协调器发起创建订单,订单创建结果返回。

  4. SAGA中央协调器发起支付请求,支付结果返回。

  5. SAGA中央协调器处理最终结果,并返回给应用程序。

SAGA中央协调器预先知道完整的事务处理流程,这可以通过配置实现。如果任意子事务失败失败,它便向每个参与者发送命令来执行补偿操作Ci(或者执行重试-向前恢复)。

其缺点很明显,既然有中央协调器就会有单点问题。

eda353a1ceaa76b1fd240c5785b825e5.png

但是优点也很多,主要有:服务之间的编排顺序明确,依赖关系简单,不会有循环依赖;耦合相对较少,参与者只需要依赖协调者接口,参与者之间没有直接依赖;参与者只需要关注自身业务,服务之间协调统一由协调器管理。

事件编排模式

事件编排模式:SAGA 中的参与者通过交换事件进行沟通,按照提前编排好的发布顺序决策和排序。

这种模式没有单点风险,由每个服务监听对应事件,并对事件做出反应。SAGA事务由应用程序发布第一个事件开始,中间服务接受到对应事件做本地事务的处理,然后继续发布事件。每一个事件由一个或者多个服务监听。当最后一个服务执行本地事务并发布事件后,Application 收到最后一个事件,事务结束,事件处理的顺序都是提前编排好的。具体参考下图:

316dabba1e2d87eab6ab45c0d67af542.png

电商订单的例子为例:

  1. 应用程序发起SAGA事务,以订单事件发布开始。

  2. 库存服务监听开始订单事件,扣减库存,成功后发布库存扣减事件。

  3. 订单服务监听库存扣减事件,创建订单,并发布订单已创建事件。

  4. 支付服务监听订单创建事件,进行支付,并发布订单已支付事件。

  5. 应用程序监听支付成功事件,SAGA事务结束。

事件/编排是实现 SAGA 模式的自然方式,它通过事件串联各个服务,实现了服务之间的松耦合。并且实现简单,只需要在执行本地事务时发布事件。如果事务涉及 2 至 4 个步骤,则可能是非常合适的。

但是有一些缺点:因为代码中没有明显的编排逻辑,所以可能会比较难理解;服务之间可能会有循环依赖;因为需要订阅事件,所以随着服务的变更可能有漏定的风险,每次需要明确评估影响,保持下游业务订阅的完整性。

SAGA 实践

SAGA 使用条件

SAGA 的使用上有一些限制条件:

  1. SAGA 只允许两个层次的嵌套,顶级的 SAGA 事务和简单子事务。

  2. 每个子事务之间是独立的,各自保证原子性。

  3. 全局SAGA之间无法保证隔离性。

  4. 补偿事务Ci只能从语义或者业务角度撤消了事务Ti的行为,但未必能将数据库返回到执行Ti时的状态。

关于补偿,说明一下。比如用户使用了红包来支付,但是部分订单退款,这时候我们无法补发原价值的红包。但是我们可以在业务上进行补偿,比如重新拍发一个对应退款金额的新红包。

ACID特性保证

SAGA 不提供ACID保证,因为原子性和隔离性不能得到满足,具体如下。

  • 原子性(Atomicity):只能业务上保证,不是严格的原子性。

  • 隔离性(Isolation):不能保证,不同SAGA事务之间中间结果可见。

  • 一致性(Consistency):保证最终一致性,但是中间状态会不一致。

  • 持久性(Durability):可以保证。

TCC对比

  1. 看起来和TCC很相似,但是和TCC相比,SAGA 没有“预留”动作,每个子事务的 T 操作直接提交数据。

  2. 因为没有预留数据,所欲 TCC 可以保证隔离性,但是 SAGA不行。

  3. 但也因为没有预留动作,SAGA 在一些场景下实现简单,并且少一次网络通信过程。

  4. SAGA适合无法提供 Try 接口的场景(比如对接银行),这点TCC无法做到。

适用场景

  • 事务参与者含第三方或者无法提供TCC预留接口。

  • 事务流程长,涉及系统多。

  • 常用于银行、金融、贷款,或者技术架构不统一的复杂分布式场景。

优缺点

优点:

  • 性能较高,无需锁定资源,子事务直接提交。

  • 采用事件驱动模式,吞吐量更高。

缺点:

  1. 无法提供原子性和隔离性保证。

  2. 有一定业务侵入性,逆向接口不一定好实现。

  3. 如果采用命令协调模式有单点风险,需要做好日志记录和重试。

最后,欢迎大家提问和交流。

加入讨论群是升职加薪第一步!

回复:加群

be354f9595d73d5810c0ac27481d18a7.jpeg

点赞是一种美德,如对您有帮助,欢迎评论和分享,感谢阅读!

开发攻城狮必备的Linux虚拟机搭建指南|原创

2023-05-01

da2869f16fbfbb1e64ca29cdb718e23c.jpeg

2023年,逆势拿到大厂Offer,我怎么做?|原创

2023-04-22

9b7bb1ed6bb8913fef91d4d44d6b6eab.jpeg

一文读懂MySQL的RedoLog写入机制和配置|原创

2023-04-05

249a628baa663f26b1e90f9c09431400.jpeg

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

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

相关文章

使用maven引入第三方jar包以及打包

我们知道,Maven 是通过仓库对依赖进行管理的,当 Maven 项目需要某个依赖时,只要其 POM 中声明了依赖的坐标信息,Maven 就会自动从仓库中去下载该构件使用。但在实际的开发过程中,经常会遇到一种情况:对接第…

《基于智能手机PPG信号处理和机器学习的非侵入式血糖监测系统》阅读笔记

目录 一、论文摘要 二、论文十问 Q1:论文试图解决什么问题? Q2:这是否是一个新的问题? Q3:这篇文章要验证一个什么科学假设? Q4:有哪些相关研究?如何归类?谁是这一课…

单片机GD32F303RCT6 (Macos环境)开发 (十五)—— i2c1采用DMA方式的读写函数

i2c1采用DMA方式的读写函数 1、关于i2c1的DMA的映射如图 2、关于代码的宏定义配置 Application目录的Makefile中 ENABLE_I2C_TEST yes才会编译I2C1的相关代码。 同时修改i2c.h文件,定义I2C1_MODE为I2C1_MODE_DMA,这样i2c1的配置为dma模式。 #define …

Microelectronic学习章节总结(3)-- gate level to physical level design

文章目录 数字逻辑设计的主要流程logic familyCMOSTransistor实现的时序逻辑 PSUDO-NMOSDCVSL(Differential Cascode Voltage Swing Logic)DOMINOC2MOS(Clocked CMOS)TSPC(True Single Phase Clocking) Transistor behaviorCMOS i…

【C生万物】 指针篇 (进级) 00

欢迎来到 Claffic 的博客 💞💞💞 👉 专栏:《C生万物 | 先来学C》👈 前言: 前面已经带大家学习了初级的指针,先回顾一下重点:指针是用来存…

数据库sql语句(视图的创建)

例题: 建表:要注意各表之间的索引联系,建表先后顺序很重要,不然建不了,例如先建dept,在建其他表,先在dept插入数据,再在其他表插入数据 (1) create table …

SW simulation解算器选取

接下来重点介绍以下4种解算器,并对解算器进行实际的计算测试。1)Direct sparse解算器:稀疏矩阵解算器,目前使用最为广泛也是发展最为成熟的解算器,几乎所有的有限元分析软件都有该解算器。它可以用于大多数计算模型,堪…

<IBM> 《HA网卡确认方法》

《HA网卡确认方法》 1 HA IP地址类型2HA IP地址设置原则3 HA网卡日常查看方法3.1 查看hosts文件3.2 查看网卡和IP 4 通过命令方式直接查看5 直接查看HA配置4 HA网卡SMIT查看方法(暂不完整)4.1 根据hosts文件确认IP对应的别名4.2 根据serviceIP确认Persis…

Django SQL注入漏洞分析(CVE-2022-28346)

漏洞简介 Django 在2022年发布的安全更新&#xff0c;修复了在 QuerySet 的 annotate()&#xff0c; aggregate()&#xff0c; extra() 等函数中存在的 SQL 注入漏洞。 影响版本 2.2< Django Django <2.2.28 3.2< Django Django ❤️.2.13 4.0< Django Django &…

白盒测试的静态和动态

白盒测试的静态和动态 静态白盒测试 检查设计和代码 静态测试是指测试非运行部分——检查和审查。白盒测试是指访问代码&#xff0c;能够查看和审查。静态白盒测试实在不执行的条件下有条理地仔细审查软件设计、体系结构和代码&#xff0c;从而找出软件缺陷的过程。有时也称为结…

SpringBoot中@ControllerAdvice/@RestControlAdvice+@ExceptionHandler实现全局异常捕获与处理

场景 在编写Controller接口时&#xff0c;为避免接口因为未知的异常导致返回不友好的结果和提示。 如果不进行全局异常捕获则需要对每个接口进行try-catch或其他操作。 可以对Controller进行全局的异常捕获和处理&#xff0c;一旦发生异常&#xff0c;则返回通用的500响应码与…

洁净环境GMP 要求悬浮粒子 浮游菌 高效过滤器检漏验证所需仪器

lighthouse尘埃粒子计数器 北京中邦兴业是美国lighthouse中国区核心代理服务商&#xff0c;各类型号尘埃粒子计数器均有现货可发。常见尘埃粒子计数器类型&#xff1a;便携式&#xff08;台式&#xff09;、手持式、在线式、液体式。 客户现场 lighthouse浮游菌采样器 北京中…

nginx(七十五)nginx与Vary响应头细节探讨

一 Vary ① nginx与Vary有关联的地方 nginx源码分析处理Vary响应头的逻辑 CORS和缓存 gzip_vary 1) gzip_vary on 如果设置为开启2) 服务器返回数据时会在头部带上"Vary:Accept-Encoding"的标识3) 客户端便可以知道获取到的数据是否已经被压缩,默认为关闭 prox…

ros获取typec-usb摄像头

确保usb或者typec摄像头插在主机上,我这里是typec摄像头&#xff0c;使用了一个usb-typec转接头。 windows在设备管理器中查看是否存在端口&#xff0c;如果没有&#xff0c;可以使用下面的软件进行尝试。 链接&#xff1a;https://pan.baidu.com/s/1hxp3m68W6NjY-3D7q8rGnA 提…

Linux线程同步(1)——一个例子看懂为什么需要线程同步?

对于一个单线程进程来说&#xff0c;它不需要处理线程同步的问题&#xff0c;所以线程同步是在多线程环境下需要注意的问题。线程的主要优势在于&#xff0c;资源的共享性&#xff0c;譬如通过全局变量来实现信息共享&#xff0c;不过这种便捷的共享是有代价的&#xff0c;那就…

postman处理各种请求数据

1、后台request接收postman参数 2、后台单个参数接收postman 3、后台RequestParam参数接收postman 注意事项&#xff1a;情况一&#xff1a;全部都是单个字符串的 情况二&#xff1a;有可能是一个json对象序列化成字符串过来的&#xff0c;那么需要在form-data中设置 …

区间预测 | MATLAB实现QRCNN-LSTM卷积长短期记忆神经网络分位数回归时间序列区间预测

区间预测 | MATLAB实现QRCNN-LSTM卷积长短期记忆神经网络分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRCNN-LSTM卷积长短期记忆神经网络分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于QRCNN-LSTM分位数回…

Elasticsearch:如何在 Elasticsearch 中存储复杂的关系数据

在传统的数据库中&#xff0c;对数据关系的描述无外乎三种&#xff1a;一对一、一对多和多对多关系。 如果有关系相关的数据&#xff0c;我们一般在建表的时候加上主外键。 建立数据链接&#xff0c;然后在查询或者统计中通过 join 恢复或者补全数据&#xff0c;最后得到我们需…

Springboot +Flowable,设置流程变量的方式(二)

一.简介 为什么需要流程变量。 举个例子&#xff0c;假设有如下一个流程&#xff0c;截图如下&#xff1a; 这是一个请假流程&#xff0c;那么谁请假、请几天、起始时间、请假理由等等&#xff0c;这些都需要说明&#xff0c;不然领导审批的依据是啥&#xff1f;那么如何传递…

软件测试面试宝典,最常见的7个高频面试题(附答案,建议收藏)

收集了2022年所有黑马学员的面试题后&#xff0c;负责就业的黑马讲师们整理出了7个高频出现的面试题&#xff0c;一起来看看。 高频问题1&#xff1a;请自我介绍下&#xff1f; 高频问题2&#xff1a;请介绍下最近做过的项目&#xff1f; 高频问题3&#xff1a;请介绍下你印象…