分布式事务?哪几种方式实现?一文看懂!

什么是分布式事务

        分布式事务是指在分布式系统中涉及到多个数据库或多个应用程序之间的事务处理,这些数据库或应用程序可能分布在不同的物理节点上,甚至可能位于不同的地理位置。在分布式事务中,需要确保所有参与者的事务操作都能够保持一致性,即所有参与者的事务要么全部提交成功,要么全部回滚。

        举个例子, 比如说我们在是春晚的直播舞台, 每个城市的场地需要安排乐队、灯光、音响等。为了确保音乐会成功,每个地方的准备工作必须协调一致,要么所有城市都准备妥当顺利开演,要么任何一个地方出问题了,所有城市都取消。

        假设一个电商系统,用户下单后需要扣减库存、扣减账户余额、生成订单等操作。在单机环境下,可以将这些操作放在同一个事务中,保证原子性、一致性和持久性。但在分布式环境下,可能存在多个服务(如库存服务、账户服务、订单服务)分布在不同的物理节点上,此时需要确保所有服务操作的事务都能够同步进行,避免出现数据不一致的情况。

        为了解决分布式事务的问题,出现了一些分布式事务解决方案,如XA协议、TCC事务、最大努力通知等。这些解决方案的实现方式各不相同,但都需要考虑如何确保所有参与者的事务操作能够保持一致性,以及如何处理可能出现的异常情况。

市面上常见的分布式事务的解决方案

        分布式事务的目的是保证分布式系统中的多个参与方的数据能够保证一致性。

1.强一致性

        1.二阶提交

        如果想要实现强一致性,那么就一定要引入一个协调者,通过协调者来协调所有参与者来进行提交或者回滚。所以,这类方案包含基于XA规范的二阶段及三阶段提交、以及支持2阶段提交。

        所谓的两个阶段是指:第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)

        一阶段提交时,将数据和回滚日志记录在同一本地事务 二阶段是回滚一阶段的 日志进行反向补偿(如果一个事务失败,其他成功的事务将会回滚)

        存在的问题

                 1、同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。

                2、单点故障。由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)

        2.三阶提交

        3PC最关键要解决的就是协调者和参与者同时挂掉的问题,所以3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。

        相比于二阶提交的优点就是,会去询问上一个协调者是不是执行成功了。比如说我们约了一个朋友后天去吃饭(CanCommit), 朋友也都安排好时间答应了,到第二天,我会和朋友打电话,确认明天是否能够正常出行(PreCommit), 但是到第三天朋友会临时有急事, 就不去了, 然而这个时候我们就可以在出门前和他打一个电话, 询问他今天是否能正常出行(DoCommit),然后朋友就会给我们一个结果, 能不能出门(commit操作), 如果不行的话我们就只能改约了。

      相比于2PC的优点就是:如果挂掉的那台机器已经执行了commit,那么协调者可以从所有未挂掉的参与者的状态中分析出来,并执行commit。如果挂掉的那个参与者执行了rollback,那么协调者和其他的参与者执行的肯定也是rollback操作。

        存在的问题

                在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,会继续进行事务的提交。比如说我们第三天出门的时候,打电话给朋友没有接到, 我们会认为他已经出门了, 我们也会继续进行操作 。所以,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。

2.最终一致性

        1.基于本地消息表实现分布式事务

                本地消息表其实也是借助消息来实现分布式事务的。

                这个方案的主要思想是将分布式事务拆分为本地事务和消息事务两个部分,本地事务在本地数据库中进行提交或回滚,而消息事务则将消息写入消息中间件中,以实现消息的可靠投递和顺序性。一般来说的做法是,在发送消息之前,先创建一条本地消息,并且保证写本地业务数据的操作,和写本地消息记录的操作在同一个事务中。这样就能确保只要业务操作成功,本地消息一定可以写成功。然后再基于本地消息,调用MQ发送远程消息。消息发出去之后,等待消费者消费,在消费者端,接收到消息之后,做业务处理,处理成功后再修改本地消息表的状态。

                简单来说, 就是我们A服务创建了一个本地消息, 基于本地消息发送给B服务, B服务接受到消息后消费, 然后再发送消息到A服务,消息发出去之后,等待A消费者消费,在消费者端,接收到消息之后,做业务处理,处理成功后再修改A本地消息表的状态。

            这里我们只需要关注几个节点 如果3发送消息节点失败, 我们可以根据本地消息表的轮询,确保MQ能够正常到B服务,如果6,7失败, 这个时候就比较特殊了, 因为其实两个服务的数据其实是一致的, 但是A服务的本地消息表状态是错误的...., 这个时候我们可以基于3 去发送消息, 在上方改进, 查询B服务的状态, 如果消费成功后, 则修改A的本地消息表的状态。

缺点

        1、消息堆积扫表慢
        2、集中式扫表会影响正常业务
        3、定时扫表存在延迟问题 

2.最大努力通知

                所谓最大努力通知,换句话说就是并不保证100%通知到。这种分布式事务的方案,通常也是借助异步消息进行通知的。

        发送者将消息发送给消息队列,接收者从消息队列中消费消息。在这个过程中,如果出现了网络通信故障或者消息队列发生了故障,就有可能导致消息传递失败,即消息被丢失。因此,最大努力通知无法保证每个接收者都能成功接收到消息,但是可以尽最大努力去通知。

        下面是一个简单的例子来说明最大努力通知的过程。假设有一个在线商城系统,顾客可以下订单购买商品。当顾客成功下单后,通知顾客订单已经确认。这个通知就可以采用最大努力通知的方式。

        最大努力通知这种事务实现方案,一般用在消息通知这种场景中,因为这种场景中如果存在一些不一致影响也不大。

3.seata实现分布式事务

        AT 模式:尽管设计为提供强一致性,但在分布式系统中完全实现强一致性是具有挑战性的,尤其是在面对网络分区或节点故障时。因此,尽管AT模式致力于达到强一致性,它在某些故障场景中可能只能保证最终一致性。
        TCC 和 Saga 模式:这两种模式都设计为支持最终一致性。它们允许更大的灵活性和可伸缩性,因为它们通过明确的补偿机制来处理事务的不同阶段,从而逐步达到全局的一致性。

如何选择 

在选择一个分布式事务方案的时候,需要考虑很多因素,结合自己的业务来做考量选择。一般来说可以有以下几种选择方式:

1、实现成本:根据项目开发和维护的难度、成本等方面来选择合适的分布式事务方案。这几种方案中,TCC和2PC的实现成本最高,业务侵入性也比较大。

另外,事务消息、本地消息表和最大努力通知都依赖消息中间件,所以如果已有业务已经接入了消息中间件的话,那么使用成本还算可控,否则就需要考虑消息中间件部署、维护和接入成本。而且同样是消息中间件,也不是所有的都支持事务消息,这个也是需要考量的一个重要因素。

2、一致性要求:在一致性方面,2PC和TCC属于是可以保证强一致性的,而其他的几种方案是最终一致性的方案。

根据业务情况,比如下单环节中,库存扣减和订单创建可以用强一致性来保证。而订单创建和积分扣减就可以用最终一致性即可。而对于一些非核心链路的操作,如核对等,可以用最大努力通知即可。

3、可用性要求:根据CAP理论,可用性和一致性是没办法同时保证的,所以对于需要保证高可用的业务,建议使用最大努力通知等最终一致性方案;对于可用性要求不高,但是需要保证高一致性的业务,可使用2PC等方案。

4、数据规模:对于利用消息中间的这种方案,其实不是特别适合业务量特别大的场景,有可能出现消息堆积导致一致性保障不及时。对于数据量大的场景,可以考虑Seata方案。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows Nginx 服务器部署并推流

环境 开发环境:windows 开发工具:ffmpeg、nginx、nginx-rmtp-module、vlc media player Nginx Nginx是一个高性能的HTTP和反向代理web服务器,并且支持rtmp,不过rtmp是作为一个nginx的一个模块。 对于linux系统,需要另…

IIS配置SSL,根据pem和key生成pfx,openssl的版本不能太高

1、生成pfx文件 供应商给的文件是pef和key后缀的两个文件,在IIS里不好导入(如果有知道好导入的可以给我留言,谢谢。)。 1.1 下载OpenSSL工具,并安装。 主要用于将.pem文件转成.pfx文件。 下载OpenSSL的链接:http://slproweb.com/…

【RAG 博客】RAG 应用中的 Routing

Blog:Routing in RAG-Driven Applications ⭐⭐⭐⭐ 根据用户的查询意图,在 RAG 程序内部使用 “Routing the control flow” 可以帮助我们构建更实用强大的 RAG 程序。路由模块的关键实现就是一个 Router,它根据 user query 的查询意图&…

VTK官方示例

VTK官方示例 -vtk字體 #!/usr/bin/env python# noinspection PyUnresolvedReferences import vtkmodules.vtkInteractionStyle # noinspection PyUnresolvedReferences import vtkmodules.vtkRenderingFreeType # noinspection PyUnresolvedReferences import vtkmodules.vtk…

【MySQL】基本操作

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:MySQL 目录 👉🏻创建和删除数据库👉🏻数据库编码集和数据库校验集校验规则对数据库的影响 👉&…

GT2505HS-VTBD 三菱触摸屏手持式5.7寸型

GT2505HS-VTBD 三菱触摸屏手持式5.7寸型 GT2505HS-VTBD参数,GT2505HS-VTBD用户手册,GT2505HS-VTBD使用手册GT2505HS-VTBD参数说明:手持式5.7吋型,VGA 640*480,TFT彩色液晶屏,65536色,内存32MB,DC24V,内置以太网接口。 GT2505HS-VT…

【GlobalMapper精品教程】079:投影坐标系转地理坐标系(UTM转WGS1984/2000)

文章目录 一、矢量UTM转WGS1984/20001. UTM转WGS19842. UTM转CGCS2000二、栅格UTM转WGS1984/2000一、矢量UTM转WGS1984/2000 加载配套实验数据(data079.rar)中的矢量数据,如下所示: 查看源坐标系:双击图层的,图层投影选项卡,为UTM投影,Zone48N。 设置系统坐标系:点击…

jupyter_lab修改默认目录

1、新版本的jupyter如果按照网上说的只修改jupyter_notebook_config.py这个文件没啥用,我在实际修改过程中遇到了如下报错。 经过各种尝试,还需要修改jupyter_notebook_config.py这个配置文件 2、不废话,直接上步骤 在Jupyter Notebook或者c…

2024年10大AI动画工具

在当今快节奏的数字环境中,动画师和内容创作者不断寻求创新工具来提高他们的工作效率和创造力。随着人工智能的出现,动画发生了显着的转变,因此提供了大量的选项,使图像无缝地栩栩如生。 无论你是一位有抱负的动画师还是经验丰富…

#include《初见C语言之顺序表的增删查改》

目录 一、顺序表 二、顺序表的分类 三、顺序表的实现前期准备 第一步,确定需要的文件 第二步,开始分析 四、顺序表的实现 1.初始化 2.销毁 3.申请空间 4.打印 5.尾插 6.头插 7.尾删 8.头删 9.指定位置之前插入 10.指定位置之前删除 11.…

grid的常见使用场景

场景1&#xff1a;固定几列显示&#xff0c;显示不下会自动换行 <div id"container"><div class"item item-1">1</div><div class"item item-2">2</div><div class"item item-3">3</div>&l…

vscode go语言开发中在任意包运行和调试代码 Example使用方法

一般情况下我们在进行go语言开发的时候我们都需要创建一个main方法和main包才能运行go代码&#xff0c; 针对这个问题&#xff0c;go语言给我们内置了功能强大的testing测试框架&#xff0c; 其中一个很有意思的Example测试就非常的方便使用。 他不管你在什么包&#xff0c;也…

LNMP环境部署WordPress——使用源码包安装方式部署环境

目录 一.前提准备 二.源码安装Mysql 1.MySQL类型 2.MySQL 版本说明 3.MySQL 安装方式 3.1 yum 安装 3.2 编译安装 3.3 二进制安装 3.4 rpm 安装 4. 编译安装MySQL5.7 4.1 清理安装环境 4.2 创建mysql用户 4.3 从官网下载tar包 4.4 安装编译工具 4.5 解压 4.6 …

Vue3:路由

1. 路由简介 在Vue3中&#xff0c;路由是一个核心概念&#xff0c;特别是在构建单页面应用程序&#xff08;SPA&#xff09;时。以下是Vue3中路由的基本概念&#xff1a; 1. **路由&#xff08;Route&#xff09;**&#xff1a;在Vue3中&#xff0c;路由是指根据特定的规则将用…

i春秋-Backdoor

题目 考点 git源码泄露 Linux文件恢复 代码审计 http 解题 参考wp https://blog.csdn.net/cbhjerry/article/details/105791056https://www.pianshen.com/article/19461342501/扫描 题目给出提示&#xff1a;敏感文件泄漏 于是使用dirsearch扫一下 python dirsearch.py -…

如何到《新英格兰医学杂志》 NEJM查找下载文献

《新英格兰医学杂志》NEJM是世界上阅读、引用最广泛、影响力最大的综合性医学期刊之一。NEJM集团出版的期刊还包括NEJM Journal Watch、NEJM Catalyst及NEJM Evidence。NEJM是一份全科医学周刊&#xff0c;出版对生物医学科学与临床实践具有重要意义的一系列主题方面的医学研究…

废品回收微信小程序基于FastAdmin+ThinkPHP+UniApp(源码搭建/上线/运营/售后/更新)

一款基于FastAdminThinkPHPUniApp开发的废品回收系统&#xff0c;适用废品回收站、再生资源回收公司上门回收使用的小程序。 一、FastAdmin框架特色功能及优势 模块化开发&#xff1a;控制器、模型、视图、JS一一对应&#xff0c;使用RequireJS进行插件机制&#xff0c;支持插…

QX----mini51单片机学习---(7)矩阵键盘

目录 1矩阵键盘的识别 2相关c语言 3实践编程 1矩阵键盘的识别 假设按列扫描按下S6P30&#xff1a;0P34&#xff1a;1然后高流向低&#xff0c;P34&#xff1a;0&#xff0c;刚开始是0xf0&#xff1a;1111 0000 后面是0xe0&#xff1a;1110 0000 &#xff0c;当是0xe0能确…

如何通过AI技术实现员工培训的革命性变革

AI个性化培训&#xff1a;开启员工潜力的新篇章 在当今这个信息爆炸的时代&#xff0c;人工智能&#xff08;AI&#xff09;技术的影响力已经渗透到社会的各个层面&#xff0c;包括教育与培训行业。AI技术正在彻底改变我们获取知识与技能的方式&#xff0c;特别是在员工培训领域…

Offline: Overcoming Model Bias for Robust Offline Deep Reinforcement Learning

EAAI 2023 paper Intro model-free的离线强化学习由于价值函数估计问题存在训练的稳定性以及鲁棒性较低。本文提出基于模型的方法&#xff0c;同构构建稳定的动力学模型帮助策略的稳定训练。 method 本文基于模型的方法&#xff0c;所构造的转移模型输入状态动作&#xff0…