分布式事务6种解决方案(超详细)

2023-11-01

分布式事务六种解决方案

前言

事务想必大家并不陌生,严格意义上讲事务应该具备ACID,目前常见的分布式事务解决方案包括2PC、3PC、TCC、本地消息表、消息事物、最大努力通知等。

ACID

  • 原子性:一个事物内的所有操作都要全执行或者都不执行
  • 一致性:事务前后数据的完整性必须保持一致
  • 隔离性:多个事务并发执行,不能被其他事物的操作所干扰
  • 持久性:事务一旦提交,它的改变应该是持久性的

分布式事务

分布式事务就是要在分布式系统中实现事物,它其实就是多个本地事物的结合,对于分布式事务几乎无法满足ACID,其实对于单机事物而言大部分情况也无法满足ACID,不然数据库怎么会有四种隔离级别呢?所以在分布式的领域里也无法全部满足。

2PC(二阶段提交)同步阻塞协议

二阶段提交是一种强一致性设计,2PC引入了一个事物协调者的角色来协调管理各参与者的提交和回滚,二阶段分别指:准备、提交两个阶段,它是一种尽可能保证强一致性的分布式事务,所以它是同步阻塞的,总体而言效率低,而且存在协调者单点故障问题,极端情况下无法保证数据一致性
在这里插入图片描述

准备阶段

协调者会给各参与者发送准备命令,它主要是为了对事物进行提交。

提交阶段

同步等待所有资源的响应之后就进入了提交阶段,这里提交阶段并不是只是提交,也可能是表示回滚。

在这里插入图片描述

假如在第一阶段有一个参与者失败,那么协调者就会向所有参与者发送回滚请求,也就是分布式失败

在这里插入图片描述

那如果二阶段提交失败怎么办?(两种情况,其实都是进行重试操作)

  1. 第二阶段执行的是回滚事务操作,那么就会不断重试,直到所有参与者都回滚,不然那些第一阶段准备成功的参与者会一直阻塞着
  2. 第二阶段执行的是提交事物操作,那么也会不断重试,因为部分参与者可能成功,这时候只能硬着头皮进行重试,直到重试成功。

首先2PC是一个同步阻塞协议,像第一阶段协调者会等待所有参与者响应才会进行下一步操作,当然第一阶段的协调者有超时机制,假设因为网络原因没有收到参与者的响应或某参与者挂了,那么超时后就会判断事物失败,向所有参与者发送回滚命令。

第二阶段协调者没法超时,因为部分参与者已经提交成功了,所有必须要不断重试。

协调者故障分析(协调者是一个单点,存在单点故障问题)
  1. 假设协调者在发送准备命令之前挂了,等于事物还没开始(影响不大)
  2. 假设协调者在发送准备命令之后挂了,这就不行了,事务已经开始了,不仅事务无法执行下去,还会因为锁定一些公共资源而阻塞系统其他操作
  3. 假设协调者在发送回滚事务命令之前挂了,这事务也无法执行下去,且在第一阶段那些准备成功的参与者都要阻塞着。(影响准备成功的参与者,基本上就是所有参与者)
  4. 假设协调者在发送回滚事务命令之后挂了,这个还行,至少命令已经发送出去,如果有网络原因导致命令发送失败,某些参与者还会因为收不到命令而阻塞着。(影响收不到命令的参与者)
  5. 假设协调者在发送提交事物命令之前挂了,这事物无法执行下去,所有资源都阻塞着。(影响所有参与者)
  6. 假设协调者在发送提交事物命令之后挂了,这个还行,至少命令已经发送出去,如果有网络原因导致命令发送失败,某些参与者还会因为收不到命令而阻塞着。(影响收不到命令的参与者)

在这里插入图片描述

如何解决以上问题呢?如果只是因为协调者的单点故障导致服务不可用的话,协调者故障可以通过选举得到新可用的协调者

  1. 如果处于第一阶段,其实影响不大,在第一阶段的事务肯定没有提交,此时都按回滚处理就好了

  2. 如果处于第二阶段,此时分为两种情况

    • 假设参与者都没问题,此时新协调者可以向所有参与者确认它们的自身情况来推断下一步操作
    • 假设参与者挂了,比如第一个参与者收到消息并执行了,然后第一个参与者与协调者都挂了,此时其他参与者都没收到请求,新的协调者介入后,协调者询问其他参与者都说OK,但是第一个参与者它是收不到请求的

    在这里插入图片描述

    问题就出在每个参与者自身的状态只有自己和协调者知道,因此新协调者无法通过在场的参与者推断出挂了的参与者处于什么状态。

这种情况,需要引入记录来判断新的协调者来的时候要不要继续确认,例如如下的信息。

参与者ID 阶段 状态
xxxxx1 prepare success
xxxxx2 prepare success
xxxxx3 commit fail

但是就算协调者知道自己该发提交请求,那么参与者在一起挂了也没有用,因为你不知道参与者在挂之前有没有提交事物操作。

  1. 如果参与者在挂之前提交成功,新协调者确定存活的参与者都没问题,需要再次发送提交事务命令才能保证数据一致
  2. 如果参与者在挂之后事务还未提交,参与者恢复了之后数据是回滚的,此时协调者必须向其他参与者发送回滚事务命令才能保持事务一致。

所以说2PC极端情况下还是无法解决数据不一致的问题

3PC (三阶段提交)

三阶段提交出现是为了解决2PC的一些问题,相比于2PC它在参与者中引入了超时机制,并且新增了一个阶段 预提交阶段 使得参与者利用这一阶段统一各自的状态。

在这里插入图片描述

准备阶段

​ 与2PC不相同,准备阶段不会直接提交事务,而是会先询问此时的参与者是否有条件接收事务,所以它不会上来锁住所有资源,使得某些资源不可用的情况下所有参与者都阻塞着。

预提交阶段

预提交阶段的引入起到了统一状态的作用,它表明预提交阶段前所有参与者还未都回应,预提交阶段后,所有参与者都进行了回应,但是多一段交互也会导致性能的下降,大多数情况所有参与者都是可用状态,极端情况会出现问题,毕竟极端情况占比比较小。

提交阶段

​ 同步等待所有资源的响应之后就进入了提交阶段,这里提交阶段并不是只是提交,也可能是表示回滚。

在这里插入图片描述

参与者超时机制

上面我们说了2PC是同步阻塞的,上面我们分析了协调者在发送事务(提交或回滚)命令之前挂了,其影响是最大的,所有参与者都在等待着,但是如果引入了超时机制,参与者就不会傻等了。超时机制只针对于参与者,针对协调者而言,超时的问题还是存在

  • 如果是等待提交命令超时,参与者就会提交事务了
  • 如果是等待预提交命令超时,那就该干啥干啥,反正参与者事务也没有开启
  • 超时机制也可能导致数据不一致的问题,比如在等待提交超时了,参与者默认执行的是事务提交操作,但是协调者可能发送的是事务回滚请求

3PC的引入是为了解决提交阶段2PC,协调者与参与者都挂了,新选举的协调者不知道当前应该是提交还是回滚的问题,但是这也只解决了部分问题,比如他无法确定参与者到底有没有执行事务,这个是无法确定的,所以3PC通过预提交阶段可以减少故障恢复时的复杂性,但是不能保证数据一致性了。

总结

3PC针对2PC做了一些改进,主要是引入了参与者的超时机制,并新增了预提交阶段使得故障恢复时协调者决策更清晰一些,但是性能上不如2PC,2PC和3PC都会出现数据不一致的情况

TCC(Try - Confirm - Cancel)

2PC和3PC在数据库层面用的比较多,TCC则在业务分布式事务层面比较多。想要了解更多可以查看Mysql中2PC的应用

TCC指的是Try - Confirm - Cancel

  • try:指的是预留,即资源的预留和使用,注意是预留
  • Confirm:指的是确认操作,这一步其实就是真正的执行了
  • Cancel:指的是撤销操作,可以理解为把预留阶段的动作撤销了

其实从思想上来看和2PC差不多,都是先试探性的执行,如果都可以就真正的执行了,如果不行就回滚。

在这里插入图片描述

如果所示,调用者发起事务,首先发给事务管理器,然后再请求服务1、服务2、服务3,都返回预定成功后,在交给事务管理器进行事务提交或回滚。

总结

TCC的整体流程还是很简单的,难点在于业务上的定义对于每一个操作你都要定义三个动作(Try-Confirm-Cancel),这对于业务的代码侵入非常大,需要根据特定的场景和业务逻辑来设计操作。

它相比于2PC、3PC使用范围更大,但是开发量也会大,不过因为它是在业务上实现的,所有TCC可以跨数据库、跨不同的业务系统来实现事务。

本地消息表

本地消息表其实就是利用各系统本地的事务来实现分布式事务

本地消息表就是有一张存放本地消息的表,一般都是与业务表放在同一个库中,利用数据库事务来操作业务表与消息表,这样就可以保证业务表执行成功的,消息表中肯定会有相应的数据信息,然后在采用定时任务或者MQ的方式做分布式事务补偿

在这里插入图片描述

比如拿订单服务与库存服务举例,用户下单后需要生成递单以及更新库存,如果这两个服务使用不同的库,也就是我们说的分布式事务

如果4过程成功或失败,会不会对整体数据产生影响呢?

  • 如果成功,消息表的消息状态改为成功后,表明库存已经更新了。
  • 如果没有成功,消息表的状态不会发生改变,但是可以利用定时任务筛选出消息表未成功的放入MQ中,再次进行处理(此处不考虑幂等性,由业务实现)
总结

可以看出本地消息表实现是采用数据库事务实现的,利用消息表与业务表在同库中,实现事务,后续再由MQ进行事务的补偿,如果补偿失败可以利用定时任务轮询消息表中未处理的消息继续进行处理,也可以增加重试次数,最后由人工再次处理。

本地消息表不同与2PC/3PC,它是数据最终一致性的,容忍了暂时数据不一致的情况。

消息事务

RockerMQ就很好的支持了消息事务,让我们看看如何通过消息实现事务。

第一步先给MQ发送事务消息即半消息**(消息对于消费者来说还不可见),这里利用MQ的事务机制,目前RocketMQ/kafka等主流MQ都支持事务投递。**然后发送成功后在执行本地事务。

第二步根据本地事务执行的结果(成功、失败)向MQ发送Commit/RollBack请求。

第三步MQ的发送方会提供一个反查事务状态的接口,如果一段时间内半消息还没收到Commit/RollBack请求,那么MQ可以通过反查结果得知发送方事务是否执行成功,然后执行Commit/RollBack

  • 如果执行Commit那么订阅方就能收到这条消息,然后在做对应的操作,做完之后在确认消费这条消息即可
  • 如果是RollBack那么订阅方收不到这条消息,等于事务没执行过(因为MQ的事务机制进行RollBack消息是消费者不可见的)

在这里插入图片描述

其实整个过程需要回查的原因就是考虑请求4可能由于网络等原因发送失败,但是本地事务已经提交了,那MQ服务器上这条半消息就无法实现Commit/RollBack,因此,MQ服务端会定时扫描存储于事务为提交的消息,并发起回调查询该消息的事务状态。上图的5、6、7就是MQ服务端定时回查的步骤

总结

可以看出消息事务主要是利用MQ的部分特性实现的(1.支持事务投递、2.未完成的事务回调检查(可以利用RockerMQ的特征,也可以基于MQ自己实现),通过消息发送方先执行本地事务后的结果再执行其他事务最后达到最终一致性,所以消息事务也是数据最终一致性的。

最大努力通知

其实我觉得最大努力通知就是一种柔性的事务思想,它适用于对时间不敏感的业务本地消息表以及消息事务都可以成为最大努力通知的一种方案

  • 本地消息表:会有后台任务查询到未完成的消息,然后去调用对应的服务,当一个消息对此调用都失败的时候可以介入人工处理。
  • 事务消息:当半消息被commit后就成为了普通消息了,如果订阅者一直不消费或者消费不了则会重试,最后进入死信队列。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分布式事务6种解决方案(超详细) 的相关文章

  • 分布式系统的特征

    分布式系统概念与设计 读书笔记 第一章 第一章 分布式系统的特征 1 0 简介 分布式系统是其组件分布在联网的计算机上 组件之间通过传递消息进行通信和动作协调的系统 该定义引出了分布式系统的下列重要特征 组建的并发性 缺乏全局时钟 组件故障
  • 分布式锁解决方案_Zookeeper分布式锁原理

    通过召zk实现分布式锁可靠性时最高的 公平锁和可重入锁的原理 取水秩序 1 取水之前 先取号 2 号排在前面的 就可以先取水 3 先到的排在前面 那些后到的 一个一个挨着 在井边排成一队 公平锁 这种排队取水模型 就是一种锁的模型 什么是可
  • 面试官让我讲讲分布式系统容错架构,结果。。。

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 目录 TB级数据放在一台机器上 难啊 到底啥是分布式存储 啥又是分布式存储系统 某台机器宕机了咋办 Master节点如何感知到数据副本消失 如何复制副本保持足够副本数
  • 区块链学习笔记(六)——区块链的分类

    文章目录 一 强调 二 公有链 联盟链 私有链 1 公有链 2 联盟链 3 私有链 总结 一 强调 先做一下重复强调 区块链技术是集分布式存储 点对点传输 共识机制 加密算法 数据区块等概念于一体的新兴技术集合 二 公有链 联盟链 私有链
  • Jmeter Springboot Redisson分布式锁并发订单操作(下单、取消单、完成单、加库存)

    Jmeter Springboot Redisson分布式锁并发订单操作 下单 取消单 完成单 加库存 涉及知识点 java springboot mybatis开发 redis分布式锁 Redisson客户端 Jmeter各种骚操作 用户
  • 数据库如何热备份

    1 1数据库冷备份 概念 在固定的周期内 人为的将数据库中的数据进行备份 一般一式三份 缺点 1 可能会造成数据丢失 2 如果数据量很多 则可能会导致备份时间很长 并且备份不能正常完成 说明 虽然冷备份有诸多的缺点 但是最好进行冷备份 因为
  • 基于 Zipkin的链路追踪

    Zipkin介绍 Zipkin 是 Twitter 的一个开源项目 它基于 Google Dapper 实现 它致力于收集服务的定时数据 以 解决微服务架构中的延迟问题 包括数据的收集 存储 查找和展现 我们可以使用它来收集各个服务器 上请
  • Kafka——Mac搭建kafka环境

    1 下载Kafka安装包 下载地址 将压缩包移动到 usr local mv kafka 2 12 3 1 0 tgz usr local 解压 tar zxvf kafka 2 12 3 1 0 tgz 2 启动 启动zookeeper
  • Redis 分布式缓存

    分布式缓存 单点 Redis 的问题及解决 数据丢失 实现Redis数据持久化 并发能力 搭建主从集群 实现读写分离 存储能力 搭建分片集群 利用插槽机制实现动态扩容 故障恢复能力 利用哨兵机制 实现健康检测和自动恢复 RDB RDB全称R
  • 项目实战之RabbitMQ冗余双写架构

    作者名称 DaenCode gt https blog csdn net 2302 79094329 作者简介 啥技术都喜欢捣鼓捣鼓 喜欢分享技术 经验 生活 人生感悟 尝尽人生百味 方知世间冷暖 所属专栏 项目所感所想 gt https
  • 基于一致性理论的孤岛微电网分布式控制策略研究(Simulink仿真实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 仿真搭建 2 2 优化控制
  • 在异构系统中学习应用的流迭代分布式编码计算研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现
  • MQ - KAFKA 基础篇

    1 KAFKA的核心组件 API Producer API 它允许应用程序向一个或多个 topics 上发送消息记录 Consumer API 允许应用程序订阅一个或多个 topics 并处理为其生成的记录流 Streams API 它允许
  • 深入理解软件测试中的Web请求流程!

    在软件开发的过程中 软件测试是不可或缺的一环 它有助于确保软件系统的稳定性 可靠性和安全性 而在众多测试中 Web请求流程的测试显得尤为重要 因为几乎所有的现代应用都离不开网络交互 接下来我们将深入探讨软件测试中完整的Web请求流程 帮助大
  • 不会做项目惨遭部门领导批评,连刷35天分布式小册轻松拿下

    互联网发展到今天 用户数量越来越多 产生的数据规模也越来越大 应用系统必须支持高并发访问和海量数据处理的需求 对比集中式架构 分布式系统由于具有可扩展性 可以动态扩展服务和存储节点 使用廉价的机器构建高性能的服务 更适合如今的互联网业务 分
  • 一文弄懂事件Event与Kafka的区别

    事件 Event 和 Apache Kafka 是两个概念层面上有所不同的东西 它们在应用程序中的作用和使用场景也有很大的差异 1 概念和定义 事件 Event 事件是 系统内发生 的特定事情或状态变化的表示 在编程和软件设计中 事件通常被
  • 使用 Helm Chart 部署分布式 GreptimeDB

    GreptimeDB 作为云时代基础设施的时序数据库 从第一天开始就积极拥抱云原生技术 将数据库部署在 Kubernetes 上可以提供可伸缩性 自愈能力和简化的部署和管理 从而为应用程序提供了强大的弹性和可靠性 Helm 是一个用于管理
  • 考虑极端天气线路脆弱性的配电网分布式电源配置优化模型【IEEE33节点】(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现
  • 手把手教你使用HarmonyOS本地模拟器

    我们通过下面的动图来回顾下手机本地模拟器的使用效果 本期 我们将为大家介绍HarmonyOS本地模拟器的版本演进 并手把手教大家使用HarmonyOS本地模拟器 一 本地模拟器的版本演进 2021年12月31日 经过一个版本的迭代优化 随D
  • 2024年华为Harmony OS走到新里程碑:取代iOS成为国内第二大智能手机操作系统

    前言 如果要问2024年最火的技术是什么 那鸿蒙开发必须占据一些位置 HarmonyOS是华为自主研发的物联网操作系统 经历四年多的发展已构建起全新的智慧生态体系 彻底改变了智能终端的交互方式 当时鸿蒙生态的智能设备已超过7亿台 同时还带来

随机推荐

  • Hill密码的加密与解密

    Hill密码原理 首先随机生成或选取一个密钥矩阵 该矩阵必须是可逆的 过程如下图所示 在加密过程中 先将明文分为三个字母一组 不足的用 X 代替 然后将其转化成数字 如0 A 得到每个字母所对应的数字 再与密钥矩阵相乘 得到的数字转成字母
  • BUCK/BOOST电路原理分析

    Buck变换器 也称降压式变换器 是一种输出电压小于输入电压的单管不隔离直流变换器 图中 Q为开关管 其驱动电压一般为PWM Pulse width modulaTIon脉宽调制 信号 信号周期为Ts 则信号频率为f 1 Ts 导通时间为T
  • python自动化写入word文件

    工具包使用python docx Github页面 https github com python openxml python docx 官网教程 https python docx readthedocs io en latest in
  • K8S的架构及工作原理

    1 Master和Node 1 Master K8S中的Master是集群控制节点 负责整个集群的管理和控制 在Master上运行着以下关键进程 kube apiserver 提供了HTTP Rest接口的关键服务进程 是K8S里所有资源的
  • unix 时间戳 c语言,C语言实现字符转unix时间戳

    在PHP中把字符串转成Unix时间戳是多么的方便 一个strtotime 函数就搞定了 而C语言实现就麻烦很多了 需要先转成tm类型 再得到它的Unix时间戳 附上实现代码 include include int strtotime cha
  • libcurl库的下载和安装

    目录 1 下载 2 解压 3 查看README 查看curl 1 4 查看INSTALL md 查看 configure help 5 配置configure 6 编译 拿下载安装libcurl库为例 1 下载 下载网址 单击一下这个文件
  • 算法入门篇:排序算法(一)

    引子 笔者刚刚学习自己的的一门编程语言 C语言 的时候 正在runoob上面刷经典一百道题 第一次见到排序问题 我内心是不屑的 这 不是张口就来 然后我就贡献了一整个下午的时间在一个简单的排序上面 初学者不知到排序的时候可以有交换两个值这样
  • js逆向_知识小结

    目录 一 Chrome之调试小结 chrome查看资源文件 chrome关联本地文件夹 chrome重写js文件并替换 chrome新建js文件并执行 Console打印输出勾选 断点 DOM 事件 xhr debugger 调用栈Call
  • Apex List

    请访问https trailhead salesforce com en users strailhead trailmixes prepare for your salesforce platform developer i creden
  • Probabilistic Knowledge Transfer for Deep Representation Learning(2018)----论文笔记

    Probabilistic Knowledge Transfer for Deep Representation Learning 写在前面 Abstract 1 Introduction 后续存在问题 本文提出的方法 优点 贡献 2 Re
  • BES2300x笔记(15) -- 提示音制作秘籍

    哈喽大家好 这是该系列博文的第十五篇 篇 lt lt 系列博文索引 快速通道 gt gt 一 前言 常见的TWS耳机产品中 我们极少会看到有LED灯指示 即便在板子上预留了LED 也只是用在调试阶段 实际量产时直接空贴 因为一个LED就足以
  • 【满分】【华为OD机试真题2023 JAVA&JS】最多等和不相交连续子序列

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 最多等和不相交连续子序列 知识点贪心 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给定一个数组 我们称其中连续的元素为连续子序列 称这些元素的和为连续子序列的
  • java泛型代码编写

    java泛型代码编写 泛型的由来 我们先看下面这段代码 List list new ArrayList list add 24 向集合中添加一个 Integer 类型的数据 list add Tom 向集合中添加一个 String 类型的数
  • 美团笔试-小美的元素删除

    小美的元素删除 小美有一个数组 她希望删除k个元素 使得剩余的元素两两之间互为倍数关系 你能告诉小美有多少种删除方案吗 由于答案过大 请对10 9 7模 输入描述 第一行输入两个整数n k 1 lt k lt n lt 10 3 表示数组长
  • Qt - 鼠标事件

    欢迎转载 请注明出处 https blog csdn net qq 39453936 spm 1010 2135 3001 5343 原文链接 https blog csdn net qq 39453936 article details
  • 电脑主板线路连接图解_台式机电源线接法图解(电脑主板接线图解高清

    对于组装一台电脑 主板上的跳线是最让小白装机用户头疼的事情 但其实具体跳线插法 在机箱连接的跳线接口上以及主板跳线插座上都有详细标注 我们只需要在主板上找到对应插座 插上去就好了 那么机箱上的跳线接在主板那些位置 下面精装之家分享一下台式电
  • springBoot框架简介入门教程(快速学习版)

    文章目录 回顾spring 优点 缺点 SpringBoot概述 SpringBoot特点 SpringBoot 的核心功能 SpringBoot自动配置 SpringBoot开发环境构建 SpringBoot配置文件 SpringBoot
  • 【P2P租车】宝驾租车:学大创始人李如彬再创业

    转自 http www cyzone cn a 20140708 260116 html 月底 上线仅一周的私家车共享平台宝驾租车获得500万美元天使投资 这是李如彬第二次创业 李如彬自己有20多辆车 平时大多闲置 这让他看到了机会 宝驾租
  • mysql 添加用户

    mysql 添加用户 1 旧版本的mysql添加新用户 INSERT INTO mysql user host user password select priv insert priv update priv VALUES localho
  • 分布式事务6种解决方案(超详细)

    文章目录 分布式事务六种解决方案 前言 ACID 分布式事务 2PC 二阶段提交 同步阻塞协议 准备阶段 提交阶段 协调者故障分析 协调者是一个单点 存在单点故障问题 3PC 三阶段提交 准备阶段 预提交阶段 提交阶段 参与者超时机制 总结