【分布式】分布式事务及其解决方案

目录

  • 一、分布式事务
  • 二、分布式事务的解决方案
    • 1. 全局事务
      • (1)DTP模型
      • (2) 两阶段提交协议(2PC)
        • 原理
        • 二阶段提交的缺点
      • (3)三阶段提交协议(3PC)
        • 原理
    • 2. 基于可靠消息服务
    • 3. 最大努力通知
    • 4. TCC

一、分布式事务

事务指的是一组操作,要么全部成功,要么全部失败。事务有四个特性ACID,具体涵义参考数据库原理这篇博客

这里举一个银行转账的例子来说明本地事务和分布式事务的区别。

本地事务可依赖数据库本身提供的事务特性来实现,因此以下逻辑可以控制本地事务:

begin transaction;//1.本地数据库操作:张三减少金额//2.本地数据库操作:李四增加金额
commit transation;

但是在分布式环境下,会变成下边这样:

begin transaction;//1.本地数据库操作:张三减少金额//2.远程调用:让李四增加金额
commit transation;

可以设想,当远程调用让李四增加金额成功了,由于网络问题远程调用并没有返回,此时本地事务提交失败就回滚了张三减少金额的操作,此时张三和李四的数据就不一致了。

​ 因此在分布式架构的基础上,传统数据库事务就无法使用了,张三和李四的账户不在一个数据库中甚至不在一个应用系统里,实现转账事务需要通过远程调用,由于网络问题就会导致分布式事务问题。

二、分布式事务的解决方案

1. 全局事务

(1)DTP模型

DTP模型规定了要实现分布式事务的体系结构,包含多个协议、算法和机制等,以确保分布式环境下的事务能够以一致和可靠的方式执行。

它规定了要实现分布式事务,需要三种角色:

  • AP:Application 应用系统它就是我们开发的业务系统,在我们开发的过程中,可以使用资源管理器提供的事务接口来实现分布式事务。

  • TM:Transaction Manager 事务管理器

    • 提供分布式事务的操作接口供业务系统调用。这些接口称为TX接口
    • 事务管理器管理着所有的资源管理器,通过它们提供的XA接口来同一调度这些资源管理器
    • DTP只是一套实现分布式事务的规范,并没有定义具体如何实现分布式事务,可采用2PC、3PC、Paxos等协议实现
  • RM:Resource Manager 资源管理器

    • 能够提供数据服务的对象都可以是资源管理器,比如:数据库、消息中间件、缓存等
    • 资源管理器能够提供单数据库的事务能力,它们通过XA接口,将本数据库的提交、回滚等能力提供给事务管理器调用,以帮助事务管理器实现分布式的事务管理
    • XA是DTP模型定义的接口,用于向事务管理器提供该资源管理器(该数据库)的提交、回滚等能力
    • DTP只是一套实现分布式事务的规范,RM具体的实现是由数据库厂商来完成的

DTP主要侧重于业务实现分布式事务时的体系结构,而后面介绍的2PC和3PC则侧重于实现的逻辑,相当于DTP是壳,而2PC/3PC等协议是核

举个例子,在通信的场景下,DTP的作用相当于定义了通信中需要有发送方和接受方,要求这两方都需要有发送和接收的能力,要求通过一系列的通信方式使得他们能正常通话。而2PC/3PC则是相当于定义了具体的通信逻辑,比如TCP三次握手和IP协议等等。

(2) 两阶段提交协议(2PC)

原理

两阶段提交又称 2PC,是一个非常经典的强一致、中心化的原子提交协议。两阶段提交协议经常用来实现分布式事务。

2PC协议中,节点分为两种角色

  • 事务协调者:协调事务的功能,通常一个系统中只有一个
  • 事务参与者:一般包含多个

将整个事务流程分为两个阶段:

  • 准备阶段(Prepare phase):事务协调者给每个参与者发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务操作(如写本地的redo和undo日志),但不提交,到达一种“万事俱备,只欠东风”的状态
    • 事务询问:协调者向所有的参与者发送事务预处理请求,并开始等待各参与者的响应
    • 执行本地事务:各个参与者节点执行本地事务操作,但在执行完成后并不会真正提交数据库本地事务
    • 各参与者向协调者反馈事务询问的响应:各参与者根据自身事务执行情况反馈,成功反馈yes,失败返回no
  • 提交阶段(commit phase):根据不同的情况做出相应的操作
    • 所有的参与者反馈给协调者的信息都是 Yes,则执行事务提交
    • 有一个或者多个返回 No,或有超时,回滚

在这里插入图片描述

二阶段提交的缺点
  • 性能问题:执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。也就是说从投票阶段到提交阶段完成这段时间,资源是被锁住的,对性能影响比较大。
  • 单点故障:主要指协调者发生故障,这种情况下参与者会一直阻塞下去,尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。
  • 网络分区是会数据不一致:阶段二中,当协调者向参与者发送commit请求之后,发生了网络分区,那就只有一部分参与者执行了commit,产生了数据不一致的情况

(3)三阶段提交协议(3PC)

原理

三阶段提交(Three-phase commit)是二阶段提交(2PC)的改进版本。三阶段提交协议(3PC)主要是为了解决两阶段提交协议的单点故障阻塞问题,2PC 存在的问题是当协调者崩溃时,参与者可能在协调者恢复之前保持阻塞。

增加的改进措施:

  • 增加超时机制:不只有协调者能感知参与者的超时,参与者也能感知协调者的超时,当其超时时,就释放自身的资源,不再继续阻塞
  • 在准备阶段前多加了一个准备阶段,变成有 CanCommit、PreCommit、DoCommit 三个阶段

在这里插入图片描述

过程:

  • CanCommit 阶段:协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应,这个过程很轻量,比如尝试获取数据库锁
    • 事务询问:协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应
    • 响应反馈:参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No
  • PreCommit阶段:根据第一阶段接受到的结果采取相应操作
    • 都是yes,进行预执行,参与者进行事务预提交,相应反馈
    • 有no或超时,参与者中断事务,释放其资源
  • doCommit阶段:该阶段进行真正的事务提交,也可以分为以下两种情况
    • 执行提交:协调者发送事务commit通知,参与者执行commit操作,反馈
    • 中断事务:协调者没有收到所有的ack,或者有超时情况,中断事务,参与者进行事务的rollback

几种情况示意图如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 基于可靠消息服务

通过消息中间件来实现。

假设有A和B两个系统,分别可以处理任务A和任务B。此时系统A中存在一个业务流程,需要将任务A和任务B在同一个事务中处理。下面来介绍基于消息中间件来实现这种分布式事务。

  • 在系统A处理任务A前,首先向消息中间件发送一条消息
  • 消息中间件收到后将该条消息持久化,但并不投递。此时下游系统B仍然不知道该条消息的存在。
  • 消息中间件持久化成功后,便向系统A返回一个确认应答;
  • 系统A收到确认应答后,则可以开始处理任务A;
  • 任务A处理完成后,向消息中间件发送Commit请求。该请求发送完成后,对系统A而言,该事务的处理过程就结束了,此时它可以处理别的任务了。
  • 消息中间件收到Commit指令后,便向系统B投递该消息,从而触发任务B的执行;
  • 当任务B执行完成后,系统B向消息中间件返回一个确认应答,告诉消息中间件该消息已经成功消费,此时,这个分布式事务完成。

总结一下上述过程的特点,

  • 消息中间件扮演者分布式事务协调者的角色。
  • 系统A完成任务A后,到任务B执行完成之间,会存在一定的时间差。在这个时间差内,整个系统处于数据不一致的状态,但这短暂的不一致性是可以接受的,因为经过短暂的时间后,系统又可以保持数据一致性,满足BASE理论。

上述过程中,如果任务A处理失败,那么需要进入回滚流程,如下图所示:

  • 向消息中间件发送Rollback请求。和发送Commit请求一样,系统A发完之后便可以认为回滚已经完成,它便可以去做其他的事情。
  • 消息中间件收到回滚请求后,直接将该消息丢弃,而不投递给系统B,从而不会触发系统B的任务B
    在这里插入图片描述
    Commit和Rollback指令都有可能在传输途中丢失,当出现这种情况的时候,消息中间件通过超时询问机制保证事务的一致性

询问的结果有三种

  • 提交若获得的状态是“提交”,则将该消息投递给系统B。
  • 回滚若获得的状态是“回滚”,则直接将条消息丢弃。
  • 处理中若获得的状态是“处理中”,则继续等待。
    在这里插入图片描述
    为保证一致性,消息中间件必须确保发送的消息能被下游接收到,如果超时就会重传,直到得到应答

在这里插入图片描述

在这里插入图片描述

3. 最大努力通知

是最简单的一种柔性事务,适用于一些最终一致性时间敏感度低的业务。

最大努力通知型的实现方案,一般符合以下特点:

​ 1、不可靠消息:业务活动主动方,在完成业务处理之后,向业务活动的被动方发送消息,直到通知N次后不再通知,允许消息丢失(不可靠消息)。

​ 2、定期校对:业务活动的被动方,根据定时策略,向业务活动主动方查询(主动方提供查询接口),恢复丢失的业务消息。

4. TCC

TCC分别对应Try、Confirm和Cancel三种操作

  • Try:预留业务资源
  • Confirm:确认执行业务操作
  • Cancel:取消执行业务操作

TCC实际上把数据库层的二阶段提交上提到了应用层来实现,即Try、Confirm和Cancel操作功能需业务提供

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

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

相关文章

DDoS攻击和CC攻击有什么不同之处?

DDoS是针对服务器IP发起,CC攻击针对的是业务端口。DDoS攻击打的是网站的服务器,而CC攻击是针对网站的页面攻击,用术语来说就是,一个是WEB网络层拒绝服务攻击(DDoS),一个是WEB应用层拒绝服务攻击…

【JavaWeb】HTMLCSSJavaScript

HTML&CSS&JavaScript 文章目录 HTML&CSS&JavaScript一、开发工具及在线帮助文档二、 HTML2.1 HTML&CSS&JavaScript的作用2.2 HTML基础结构2.3 HTML概念词汇解释2.4 HTML的语法规则2.5 常用标签 三、CSS3.1 引入方式3.2 CSS选择器3.3 CSS浮动3.4 CSS定位…

Linux | 从虚拟地址到物理地址

前言 本章主要讲解虚拟地址是怎么转化成物理地址的,以及页表相关知识;本文环境默认为32位机器下;如果你连什么是虚拟地址都不知道可以先看看下面这篇文章; Linux | 进程地址空间-CSDN博客 一、概念补充 页表:是一种数据…

【性能优化】CPU利用率飙高与内存飙高问题

📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于…

2023APMCM亚太杯数学建模选题建议及初步思路

大家好呀,亚太杯数学建模开始了,来说一下初步的选题建议吧: 首先定下主基调,本次亚太杯推荐选择B题。 C题如果想做好,搜集数据难度并不低,并且模型比较简单,此外目前选择的人数过多&#xff0c…

java项目之消防物资存储系统(ssm+vue)

项目简介 消防物资存储系统实现了以下功能: 管理员功能: 管理员登陆后,主要模块包括首页,个人中心,用户管理,仓库管理,物资入库管理,物资出库管理,仓库管理,物资详情管…

23年下半年软考成绩查询时间是什么时候?

一、成绩查询时间 2023年下半年软考成绩查询时间预计2023年12月份公布,成绩查询入口为计算机技术职业资格网(全国统一成绩查询时间,统一查询入口)。 二、成绩查询方法 登陆中国计算机技术职业资格网,点击“成绩查询”…

WPF实战项目十六(客户端):备忘录接口

1、新增IMemoService接口&#xff0c;继承IBaseService接口 public interface IMemoService : IBaseService<MemoDto>{} 2、新增MemoService类&#xff0c;继承BaseService和IMemoService接口 public class MemoService : BaseService<MemoDto>, IMemoService{pub…

力扣236. 二叉树的最近公共祖先(java DFS解法)

Problem: 236. 二叉树的最近公共祖先 文章目录 题目描述思路解题方法复杂度Code 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&am…

【管理运筹学】背诵手册(五)| 动态规划

五、动态规划 基本概念 阶段&#xff08;Stage&#xff09;&#xff1a;将所给问题的过程&#xff0c;按时间或空间特征分解成若干相互联系的阶段&#xff0c;以便按次序去求解每阶段的解&#xff0c;常用字母 k k k 表示。 状态&#xff08;State&#xff09;&#xff1a;…

计算机网络之网络层

一、概述 主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输 1.1网络引入的目的 从7层结构上看&#xff0c;网络层下是数据链路层 从4层结构上看&#xff0c;网络层下面是网络接口层 至少我们看到的网络层下面是以太网 以太网解决了什么问题&#xff1f; 答…

计算机网络之应用层

一、概述 引入目的&#xff1a; 为了方便用户去使用&#xff1b; 该如何方便用户使用网络呢&#xff0c;即怎样帮助用户使用网络&#xff1f; 1.用户需要知道网络资源所在的位置 2.网络上资源一定是在资源子网的主机上 3.资源子网上的主机&#xff0c;在通信子网中用IP地…

qt-C++笔记之终端Ctrl+C关闭界面和ROS节点

qt-C笔记之终端CtrlC关闭界面和ROS节点 code review! 文章目录 qt-C笔记之终端CtrlC关闭界面和ROS节点1.运行2.main.cpp3.main_window.hpp 1.运行 2.main.cpp 3.main_window.hpp

SpringCloud 微服务全栈体系(十六)

第十一章 分布式搜索引擎 elasticsearch 六、DSL 查询文档 elasticsearch 的查询依然是基于 JSON 风格的 DSL 来实现的。 1. DSL 查询分类 Elasticsearch 提供了基于 JSON 的 DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1…

【数据结构(C语言)】浅谈栈和队列

目录 文章目录 前言 一、栈 1.1 栈的概念及结构 1.2 栈的实现 1.2.1. 支持动态增长的栈的结构 1.2.2 初始化栈 1.2.3 入栈 1.2.4 出栈 1.2.5 获取栈顶元素 1.2.6 获取栈中有效元素个数 1.2.7 检查栈是否为空 1.2.8 销毁栈 二、队列 2.1 队列的概念及结构 2.2 队…

Javaweb之前后台分离开发介绍的详细解析

2.1 前后台分离开发介绍 在之前的课程中&#xff0c;我们介绍过&#xff0c;前端开发有2种方式&#xff1a;前后台混合开发和前后台分离开发。 前后台混合开发&#xff0c;顾名思义就是前台后台代码混在一起开发&#xff0c;如下图所示&#xff1a; 这种开发模式有如下缺点&a…

使用vcpkg安装库失败的解决方法

1、前言 vcpk是是一款开源的c/c库管理工具&#xff0c;尤其是在windows平台&#xff0c;可以帮助我们很好的管理各种依赖包。 在windows环境做c/c开发的人应该都深有体会&#xff0c;有时候编译需要下载一堆依赖库&#xff0c;导致搭建编译环境特别麻烦。但是&#xff0c;通过v…

前端 vue 面试题(二)

文章目录 如何让vue页面重新渲染组件间通信vue为什么要mutation、 action操作插槽、具名插槽、作用域插槽vue编译使用的是什么库&#xff1f;vue怎么实现treeshakingwebpack实现treeshaking为什么只有es module 能支持 tree shaking mixin 的作用mixin的底层原理nexTick原理vue…

预处理机制

跟着肯哥&#xff08;不是我&#xff09;学预处理机制 预处理类别 宏定义&#xff1a;#define 将文本替换为表达式或语句 条件编译&#xff1a;#ifdef、#ifndef和#if、#elif、#endif 根据标识符是否被定义选择编译代码 头文件包含&#xff1a;#include 将其他文件&#x…

Jmeter怎么实现接口关联?

用于接口测试时&#xff0c;后一个接口经常需要用到前一次接口返回的结果&#xff0c;应该如何获取前一次请求的结果值&#xff0c;应用于后一个接口呢&#xff0c;拿一个登录的例子来说明如何获取。 1、打开jmeter&#xff0c;新建一个测试计划&#xff0c;在测试计划里新建一…