分布式事务 | 2PC与3PC 详解

news2024/11/26 18:37:06

分布式事务

2PC

2PC ,两阶段提交,将事务的提交过程分成资源准备和资源提交两个阶段,并且由事务协调者来协调所有事务参与者,如果准备阶段所有事务参与者都预留资源成功,则进行第二阶段的资源提交,否则事务协调者回滚资源。

1. 第一阶段:准备阶段

由事务协调者询问通知各个事务参与者,是否准备好了执行事务,具体流程图如下:

image-20231206005858493

  1. 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待答复。
  2. 各参与者执行本地事务操作,将undo和redo信息记入事务日志中(但不提交事务)。
  3. 如参与者执行成功,给协调者反馈同意,否则反馈中止,表示事务不可以执行。

2. 第二阶段:提交阶段

协调者收到各个参与者的准备消息后,根据反馈情况通知各个参与者commit提交或者rockback回滚。

2.1 事务提交:

当第一阶段所有参与者都反馈同意时,协调者发起正式提交事务的请求,当所有参与者都回复同意时,则意味着完成事务,具体流程如下:

  1. 协调者节点向所有参与者节点发出正式提交的commit请求。
  2. 收到协调者的commit请求后,参与者正式执行事务提交操作,并释放在整个事务期间内占用的资源。
  3. 参与者完成事务提交后,向协调者节点发送ACK消息。
  4. 协调者节点收到所有参与者节点反馈的ACK消息后,完成事务。

image-20231209133335513

2.2 事务回滚

如果任意一个参与者节点在第一阶段返回的消息为中止,或者协调者节点在第一阶段的询问超时之前无法获取所有参与者节点的响应消息时,那么这个事务将会回滚,具体流程如下:

image-20231209133626507

3. 2PC 缺点

二阶段提交确实能够提供原子性的操作,但二阶段提交还是有几个缺点:

  1. 性能问题:执行过程中,所有参与节点都是事务阻塞性的,当参与者占用公共资源时,其他第三方节点访问公共资源就不得不处于阻塞状态,为了数据一致性而牺牲了可用性,对性能影响比较大,不适合高并发高性能场景。
  2. 可靠性问题:2PC非常依赖协调者,当协调者发生故障时,尤其是第二阶段,那么所有参与者就会处于锁定事务资源的状态中,导致无法继续完成事务操作。如果是协调者挂掉了,可以重新选举一个协调者,但是无法解决因为协调者当即导致的参与者处于阻塞状态的问题。
  3. 数据一致性:当二阶段中的协调者向参与者发起了commit请求操作之后,发生了局部网络异常或者在发送commit请求过程中,协调者发生了故障,这会导致只有一部分参与者接受到了commit请求。 而在这部分参与者接受到commit请求之后就会执行commit操作。但是其他部分内接到commit请求的机器则无法执行事务操作。于是整个分布式系统中,就会出现数据不一致的问题。
  4. 二阶段无法解决的问题:协调者在发出commit消息之后宕机,而唯一接受到这条消息的参与者同时也宕机了,那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没有人知道这个事务是否已经提交。

其实2PC的问题是可以规避的,那就是通过log的日志进行记录,一切的事务提交与否以log记录为主。

3PC

3PC,三阶段提交协议,是二阶段协议的改进版本,三阶段提交有两个改动点:

  1. 在协调者和参与者中都引入超时机制
  2. 在第一阶段和第二阶段中插入一个准备阶段保证了在最后提交阶段之前各个参与节点的状态是一致的

所以3PC会分3个阶段,CanCommit准备阶段,PreCommit预提交阶段,DoCommit提交阶段,处理流程如下:

image-20231209145612446

1. 阶段一:CanCommit 准备阶段

协调者向参与者发送canCommit请求,参与者如果可以提交就返回Yes响应,否则返回No响应,具体流程如下:

  1. 事务询问:协调者向所有参与者发出包含事务内容的canCommit请求,询问是否可以提交事务,并等待所有参与者答复。
  2. 响应反馈:参与者收到canCommit请求后,如果认为可以执行事务操作,则反馈yes,并进入预备状态,否则反馈no。

2. 阶段二:PreCommit阶段

协调者根据参与者的反应情况来决定是否可以进行事务的preCommit操作。根据响应情况,有以下两种可能:

2.1 执行事务:

假如所有参与者均反馈yes,协调者预执行事务,具体如下:

  1. 发送预提交请求:协调者向参与者发送preCommit请求,并进入准备阶段。
  2. 事务预提交:参与者接受到preCommit请求后,会执行本地事务操作,并将undo和redo信息记录到事务日志中,但并不提交事务。
  3. 响应反馈:如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。

image-20231209155121377

2.2 中断事务:

假如有任何一个参与者向协调者发送No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断,流程如下:

  1. 发送中断请求:协调者向所有参与者发送abort请求
  2. 中断事务:参与者收到来自协调者的abort请求之后(或者超时之后,仍为收到协调者的请求),执行事务的中断。

image-20231209155150708

3. 阶段三:doCommit阶段

该阶段进行真正的事务提交,也可以分为以下两种情况:

3.1 提交事务:
  1. 发送提交请求:协调接受到所有参与者发送的ACK响应,那么他将从预提交状态进入到提交状态,并向所有参与者发送doCommit请求
  2. 本地事务提交:参与者接受到doCommit请求之后,执行正式的事务提交,并在完成事务提交之后释放所有事务资源
  3. 响应反馈:事务提交完之后,向协调者发送ack响应
  4. 完成事务:协调者接受到所有参与者的ack响应之后,完成事务。

image-20231209155227204

3.2 中断事务:

任何一个参与者反馈no,或者等待超时后,协调者无法收到所有参与者的反馈,即中断业务

  1. 发送中断请求:如果协调者处于工作状态,向所有参与者发出abort请求
  2. 事务回滚:参与者接受到abort请求之后,利用其在二阶段记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。
  3. 反馈结果:参与者完成事务回滚之后,向协调者反馈ACK消息
  4. 中断事务:协调者接收参与者反馈的ACK消息之后,执行事务的中断

image-20231209155313301

进入doCommit阶段后,无论协调者出现问题,或者协调者与参与者之间的网络出现问题,都会导致参与者无法接受到协调者发出的doCommit请求或者abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。这其实给予改了来决定,当进入第三阶段时,说明第一阶段收到所有参与者的canCommit的响应都是Yes,所以一句话概括就是,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort,但是他有理由相信:成功提交的几率很大,比较前面收到所有的canCommit的Yes。

4. 3PC的优缺点

与2PC相比,3PC降低了阻塞范围,并且在等待超时后,协调者或参与者会中断中断事务,避免协调者单点问题,阶段三中协调者出现问题时,参与者会继续提交事务。

数据不一致的问题依旧存在,当在参与者收到preCommit请求后等待doCommit指令时,此时如果协调者请求中断事务,而协调者因为网络问题无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致

2PC和3PC都无法保证数据绝对的一致性,一般为了预防这种问题,可以添加一个报警,比如监控到事务异常的时候,通过脚本自动补偿差异的信息。

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

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

相关文章

本章主要介绍Spring Framework中用来处理URI的多种方式

1.使用 UriComponentsBuilder 构建URi 话不多说 直接上代码 UriComponents uriComponents UriComponentsBuilder.fromUriString("https://example.com/hotels/{hotel}").queryParam("q", "{q}").encode().build();URI uri uriComponents.exp…

【Gradle】创建第一个项目

文章目录 1. 前提2. 创建项目并初始化1)创建项目2)初始化项目 3. 介绍生成的文件结构4. 执行5. 包的作成 (非必须)6. 推送(非必须) 本节将继 Gradle 之初体验 安装之后,创建第一个 Hello World…

Oracle(2-18)Export and Import Utilities

文章目录 一、基础知识1. Export &Import Utilities2、Exp/lmp Utility Overview Exp/mp实用程序概述3、Before Your Use Of Exp/lmp 在您使用Exp/lmp之前4、Methods to invoke Exp/lmp 调用Exp/lmp的方法5、Import Utility for Recovery 用于恢复的导入实用程序 二、基础操…

Mac如何安装stable diffusion

今天跟大家一起在Mac电脑上安装下stable diffusion,在midjourney等模型收费的情况下如何用自己的电脑算力用上免费的画图大模型呢?来吧一起实操起来 一、安装homebrew 官网地址:Homebrew — The Missing Package Manager for macOS (or Lin…

【科研论文】检索证明、科技查新、查收查引(附教育部、科技部查新工作站名单)

文章目录 1、什么是科技查新 & 查收查引2、科技查新 & 查收查引有什么用3、如何办理科技查新 & 查收查引4、教育部科技查新工作站5、科技部认定的查新机构名单 1、什么是科技查新 & 查收查引 科技查新是国家科技部为避免科研课题重复立项和客观正确地判别科研…

Android开发——组合函数、注解与连接Android设备

1、JetPack Compose、组合函数与注解和文本修改 1、JetPack Compose:Jetpack Compose 是由 Google 推出的用于构建 Android 用户界面的现代化工具包。它是一个声明式的 UI 工具包,用于简化 Android 应用程序的用户界面设计和开发。Jetpack Compose 采用…

并发编程中常见的设计模式

文章目录 一、 终止线程的设计模式1. 简介2. Tow-phase Termination(两阶段终止模式)—优雅的停止线程 二、避免共享的设计模式1. 简介2. Immutability模式—想破坏也破坏不了3. Copy-on-Write模式4. Thread-Specific Storage模式—没有共享就没有伤害 三…

跟着官网学 Vue - 插槽

Vue 插槽是一种强大的组件通信方式。 插槽内容与出口 在 Vue 中&#xff0c;插槽是一种让父组件向子组件传递内容的方式。子组件使用 <slot> 元素作为插槽出口&#xff0c;父组件可以通过插槽内容填充这些空白区域。 示例&#xff1a; <!-- MyButton.vue --> &…

代码随想Day39 | 62.不同路径、63. 不同路径 II

62.不同路径 每次向右或者向下走两个选择&#xff0c;定义dp数组dp[i][j] 为到达索引ij的路径和&#xff0c;状态转移公式为 dp[i][j]dp[i-1][j]dp[i][j-1]&#xff0c;初始状态的第一行和第一列为1&#xff0c;从左上到右下开始遍历即可。详细代码如下&#xff1a; class Sol…

BM61 矩阵最长递增路径

题目 矩阵最长递增路径 给定一个 n 行 m 列矩阵 matrix &#xff0c;矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径&#xff0c;使这条路径上的元素是递增的。并输出这条最长路径的长度。 这个路径必须满足以下条件&#xff1a; 1. 对于每个单元格&#xff0c;你…

Flink系列之:监控Checkpoint

Flink系列之&#xff1a;监控Checkpoint 一、概览二、概览&#xff08;Overview&#xff09;选项卡三、历史记录&#xff08;History&#xff09;选项卡四、历史记录数量配置五、摘要信息&#xff08;Summary&#xff09;选项卡六、配置信息&#xff08;Configuration&#xff…

【Linux】在vim中批量注释与批量取消注释

在vim编辑器中&#xff0c;批量注释和取消注释的操作可以通过进入V-BLOCK模式、选择要注释或取消注释的内容、输入注释符号或选中已有的注释符号和按键完成。这些操作可以大大提高代码或文本的编写和修改效率&#xff0c;是vim编辑器中常用的操作之一。 1.在vim中批量注释的步…

Git----学习Git第一步基于 Windows 10 系统和 CentOS7 系统安装 Git

查看原文 文章目录 基于 Windows 10 系统安装 Git 客户端基于 CentOS7 系统安装部署 Git 基于 Windows 10 系统安装 Git 客户端 &#xff08;1&#xff09;打开 git官网 &#xff0c;点击【windows】 &#xff08;2&#xff09;根据自己的电脑选择安装&#xff0c;目前一般w…

Github 2023-12-18 开源项目周报 Top14

根据Github Trendings的统计&#xff0c;本周(2023-12-18统计)共有14个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量TypeScript项目4Python项目4Jupyter Notebook项目3非开发语言项目1JavaScript项目1Rust项目1Go项目1 基于项目…

正点原子驱动开发BUG(一)--SPI无法正常通信

目录 一、问题描述二、讲该问题的解决方案三、imx6ull的spi适配器驱动程序控制片选分析3.1 设备icm20608的驱动程序分析3.2 imx的spi适配器的驱动程序分析 四、BUG修复测试五、其他问题 一、问题描述 使用正点的im6ull开发板进行spi通信驱动开发实验的时候&#xff0c;主机无法…

Spring Boot 3 + Vue 3 整合 WebSocket (STOMP协议) 实现实时通信

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

VSCode 常用的快捷键和技巧系列(2)

一、如何让VSCode工程树显示图标 第一步&#xff1a;安装 快捷键 CtrlP &#xff0c;输入 ext install vscode-icons &#xff0c;然后点击安装插件 第二步&#xff1a;配置 安装成功后&#xff0c;点击Reload重新加载。 然后配置&#xff0c;当前图标使用VsCode-Icons Go…

Harmony4.0鸿蒙应用开发初识+实践小案例

Harmony4.0鸿蒙应用开发初识实践小案例 一、华为的“18N”产品战略 在华为HarmonyOS及全场景新品发布会上&#xff0c;华为介绍了华为“18N”三圈层全场景智慧生态解决方案&#xff0c;从而打造面向未来的全新生态&#xff0c;其中&#xff0c;1指的是手机&#xff0c;8指的是…

【LeetCode刷题笔记(8-1)】【Python】【接雨水】【动态规划】【困难】

文章目录 引言接雨水题目描述提示 解决方案1&#xff1a;【动态规划】结束语 接雨水 引言 编写通过所有测试案例的代码并不简单&#xff0c;通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例&#xff0c;但如果不了解代码背后的思考过程&#xff0c;那么这些代…