分布式事务与解决方案

news2024/9/22 17:18:46

一、什么是分布式事务

首先我们知道本地事务是指事务方法中的操作只依赖本地数据库,可保证事务的ACID特性。而在分布式系统中,一个应用系统被拆分为多个可独立部署的微服务,在一个微服务的事务方法中,除了依赖本地数据库外,还可能会调用一个或多个远程服务操作远程数据库,这种就叫做分布式事务。

在分布式事务中,如果由于网络波动导致远程调用执行成功了,但是没有及时返回结果,导致事务回滚,本地数据库回滚了,但是远程数据库已经执行成功持久化了,这就出现了不一致的情况。

二、Base理论

在CAP理论中的一致性强调的是强一致性。
BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩
写。BASE理论是对CAP中AP的一个扩展,通过牺牲强一致性来获得可用性,当出现故障允许部分不可用但要保证
核心功能可用,允许数据在一段时间内是不一致的,但最终达到一致状态。满足BASE理论的事务,我们称之为“柔
性事务”。

  • 基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。如,电商网站交易付款出
    现问题了,商品依然可以正常浏览。
  • 软状态:由于不要求强一致性,所以BASE允许系统中存在中间状态(也叫软状态),这个状态不影响系统可用
    性,如订单的"支付中"、“数据同步中”等状态,待数据最终一致后状态改为“成功”状态。
  • 最终一致性:最终一致是指经过一段时间后,所有节点数据都将会达到一致。如订单的"支付中"状态,最终会变
    为“支付成功”或者"支付失败",使订单状态与实际交易结果达成一致,但需要一定时间的延迟、等待。

前面已经学习了分布式事务的基础理论,以理论为基础,针对不同的分布式场景业界常见的解决方案有2PC、可靠消息最终一致性、最大努力通知这几种。

三、2PC —— 两阶段提交

  • P 准备阶段:事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo日志,但是先不提交事务,然后给事务管理器回复一个OK,表示准备好了。(Undo日志是记录修改前的数据,用于数据库回滚,Redo日志是记录修改后的数据,用于提交事务后写入数据文件)

  • C 提交阶段:如果所有参与者都准备好了,事务管理器就会发送一个commit消息,所有参与者再执行事务提交。如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息,所有参与者就都执行回滚。

成功情况:
在这里插入图片描述

失败情况:
在这里插入图片描述

1. XA模式 —— 强一致性

XA模式流程就如上所说,第一阶段参与者只执行不提交事务,第二阶段收到Commit信号后再进行提交。这种模式可以基于数据库的XA协议来实现。也可以基于一些第三方框架实现,比如Seata,Seata是由阿里中间件团队做的一个是开源的分布式事务框架。它是工作在应用层,不需要数据库支持XA协议,因此兼容性更好。它由事务协调器、事务管理器、资源管理器三部分组成:

  • Transaction Coordinator (TC): 事务协调器,它是独立的中间件,需要独立部署运行,它维护全局事务的运行状态,接收TM指令发起全局事务的提交与回滚,负责与RM通信协调各各分支事务的提交或回滚。
  • Transaction Manager(TM): 事务管理器,TM需要嵌入应用程序中工作,它负责开启一个全局事务,并最终向TC发起全局提交或全局回滚的指令。
  • Resource Manager (RM): 资源管理器,控制分支事务,负责分支注册、状态汇报,并接收事务协调器TC的指令,驱动分支(本地)事务的提交和回滚。

Seata的XA模式流程如下:

  • 一阶段:TM开启全局事务注册到TC 、TM调用分支RM、RM将分支事务注册到TC、RM执行SQL(但不提交!)、RM将执行状态报告给TC

  • 二阶段:TM通知提交全局事务、TC检查各分支事务状态,如果都成功,则通知RM提交。如果失败,则通知RM回滚。

XA模式优缺点:XA模式保证了强一致性,但是资源锁需要等到两个阶段结束才释放,性能较差。

2. AT模式 —— 弱一致性

AT模式是Seata中的默认模式

  • 一阶段:TM开启全局事务注册到TC、TM调用分支RM、RM将分支事务注册到TC、RM记录undolog日志、RM提交事务、TCC记录各分支状态

  • 二阶段:TM通知提交全局事务、TC检查各分支事务状态,都成功则删除undolog日志,有失败则通知所有RM根据undolog日志执行反向补偿操作回滚。

AT模式优缺点:AT模式在第一阶段就提交了事务释放了资源锁,性能较高。但是由于提前提交了事务,如果在回滚之前,有其它事务修改了数据,那么再根据undolog日志回滚后就会覆盖掉了这个修改,出现脏写问题。需要引入全局锁解决。

3. TCC模式 —— 弱一致性

TCC模式分为Try、Confirm和Cancel三个操作

  • 一阶段:通过Try操作判断是否有可用数据,有则锁住需要的资源。
  • 二阶段:如果全部try成功则执行confirm操作,完成资源的操作业务,且try成功confirm一定要成功,无论是通过重试还是人工介入。如果有try失败的,则所有try成功的节点执行Cancel操作释放预留资源。

TCC模式优缺点: try、confirm、canel需要人工手写,而且需要考虑幂等性、空回滚、悬挂判断,较为复杂、性能最好,但成本太高。

幂等性: try、confirm、canel这三个接口,要保证重试操作具有幂等性
空回滚:没有执行try操作的节点回滚时执行了cancel。解决方案:用一张“分支事务记录”记录是否执行过try操作,执行cancel时要进行查询,执行过try操作才需要回滚。
悬挂:try操作由于网络波动超时了,导致触发回滚cancel操作,在执行完cancel后try操作请求到达了,这种先cancel再try的现象就称为悬挂。解决方案:在执行一阶段事务时判断在该全局事务下,“分支事务记录”表中是否已经有二阶段事务记录,如果有则不执行Try。

在这里插入图片描述

参考:

  1. https://blog.csdn.net/m0_58600248/article/details/126271252
  2. https://blog.csdn.net/O_Dentist/article/details/130966668

四、可靠消息最终一致性

可靠消息最终一致性方案是通过消息中间件完成的,指当事务发起方执行完成本地事务后并发出一条消息,事务参与方(消息消费者)一定能
够接收消息并处理事务成功,使得所有事务参与方最终事务达到一致。

要达成这种效果需要解决以下问题:

  1. 原子性:本地事务和消息发送必须同时成功或者同时失败,具有原子性。
  2. 可靠性:事务参与方必须能够在消息队列接收到消息,接收失败可以重复接收。
  3. 幂等性: 事务参与方不能重复消费消息。

1. 本地消息表

本地数据库增加一个消息表,将本地事务操作和添加消息记录放在同一个事务中,然后后台定时任务去循环扫描这个消息表,检测到未发送的消息时就交给MQ发送,消费端收到这个消息后通过MQ回复ACK确认,发送端收到MQ反馈后再删除对应的消息记录,消费端要对收到的消息进行幂等性检查避免重复消费(发送端可能会重复发送),非重复消费则消费执行事务。
在这里插入图片描述

2. RocketMQ事务消息方案

  1. 在执行事务前会先发消息给MQ服务端,但是这个消息是不可消费状态。
  2. 然后发送方再执行本地事务,执行成功/失败后再给MQ服务端发送一个commit或者rollback事务确认消息,如果执行成功了MQ服务端再把消息投递给订阅方,如果执行失败了则直接丢弃原来的消息。
  3. 如果确认消息在中间丢失了,MQ服务端没有收到 则会定期回查事务的状态。
    在这里插入图片描述

在RocketMQ 4.3后实现了完整的事务消息,实际上其实是对本地消息表的一个封装,将本地消息表移动到了MQ 内部,解决 Producer 端的消息发送与本地事务执行的原子性问题。

五、最大努力通知

发起通知方通过一定的机制最大努力将业务处理结果通知到接收方,比如重复通知,并且发送方要提供消息校对接口,若尽最大努力仍没有通知到,此时可由接收方主动向通知方查询消息信息来满足需求。

1. MQ最大努力通知实现方案

  • 发送方通过MQ将消息发送出去。接收方收到后会回复一个ack,发送方收到ack则通知成功了。
  • 若发送方没有收到ack,则进行重传,直到超过一定次数。
  • 接收方可主动通过发送方提供的接口进行消息校对,获取需要的消息。
    在这里插入图片描述

参考:https://www.bilibili.com/video/BV1Q4411y7ip

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

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

相关文章

R语言实现神经网络(1)

#R语言实现神经网络 library(neuralnet) library(caret) library(MASS) library(vcd) data(shuttle) str(shuttle)#因变量use; table1<-structable(windmagn~use,shuttle) mosaic(table1,shadingT) mosaic(use~errorvis,shuttle) prop.table(table(shuttle$use,shuttle$stab…

当你出差在外时,怎样轻松访问远程访问企业局域网象过河ERP系统?

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻&#xff0c;不管是财务、生产、销售还是采购&#xff0c;都需要用到ERP系统来协助。…

1191. K 次串联后最大子数组之和;2171. 拿出最少数目的魔法豆;1297. 子串的最大出现次数

1191. K 次串联后最大子数组之和 核心思想&#xff1a;贪心&#xff0c;如果k < 2 那么只需要按照求最大子数组和来求即可&#xff0c;如果k>2了&#xff0c;那么如果子数组的和大于0就把它加在一起&#xff0c;如果不大于0就不要这部分。 2171. 拿出最少数目的魔法豆 …

Octree八叉树python

原理 简单示例&#xff1a; 假设我们有以下一组三维点云数据&#xff1a; points [[0.1, 0.1, 0.1],[0.4, 0.1, 0.1],[0.1, 0.4, 0.1],[0.4, 0.4, 0.1],[0.1, 0.1, 0.4],[0.4, 0.1, 0.4],[0.1, 0.4, 0.4],[0.4, 0.4, 0.4], ] 我们可以使用八叉树将这些点云数据存储在三维空…

如何构造不包含字母和数字的webshell

利用不含字母与数字进行绕过 1.异或进行绕过 2.取反进行绕过 3.利用php语法绕过 利用不含字母与数字进行绕过 基本代码运行思路理解 <?php echo "A"^""; ?> 运行结果为! 我们可以看到&#xff0c;输出的结果是字符"!"。之所以会…

干翻Dubbo系列第十一篇:Dubbo常见协议与通信效率对比

文章目录 文章说明 一&#xff1a;协议 1&#xff1a;什么是协议 2&#xff1a;协议和序列化关系 3&#xff1a;协议组成 &#xff08;一&#xff09;&#xff1a;头信息 &#xff08;二&#xff09;&#xff1a;体信息 4&#xff1a;Dubbo3中常见的协议 5&#xff1a;…

数据结构—线性表的查找

7.查找 7.1查找的基本概念 问题&#xff1a;在哪里找&#xff1f;——查找表 查找表是由同一类型的数据元素&#xff08;或记录&#xff09;构成的集合。由于“集合”中的数据元素之间存在着松散的关系&#xff0c;因此查找表是一种应用灵便的结构。 问题&#xff1a;什么查找&…

07- RTC实时时钟

RTC实时时钟 RTC实时时钟RTC时钟来源&#xff1a;RTC的特征&#xff1a;简化的RTC框图及原理简介&#xff1a;RTC由两部分组成&#xff1a;RTC相关库函数&#xff1a;库函数的讲解和使用&#xff1a;RTC配置步骤&#xff1a; 示例 RTC实时时钟 RTC时钟来源&#xff1a; RTC的特…

并发编程4:Java 中的并发基础构建模块

目录 1、同步容器类 1.1 - 同步容器类的问题 1.2 - 迭代和容器加锁 2、并发容器类 2.1 - ConcurrentHashMap 类 2.2 - CopyOnWriteArrayList 类 3、阻塞队列和生产者-消费者模式 3.1 - 串行线程封闭 4、阻塞方法与中断方法 5、同步工具类 5.1 - 闭锁 -> CountDow…

【分布式共识算法】Basic Paxos 算法

basic paxos算法&#xff1a;描述的是多个节点就某个值达成共识。 muti-paxos 算法&#xff1a;描述的是执行多个basic paxos实例&#xff0c;就一系列值达成共识。 共识其实&#xff0c;比如当多个客户端请求服务器&#xff0c;修改同一个值X 多个阶段达成共识。 原理 角色…

213、仿真-基于51单片机智能电表电能表用电量电费报警Proteus仿真设计(程序+Proteus仿真+原理图+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、原理图 五、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选…

ARM DIY 硬件调试

前言 之前打样的几块 ARM 板&#xff0c;一直放着没去焊接。今天再次看到&#xff0c;决定把它焊起来。 加热台焊接 为了提高焊接效率&#xff0c;先使用加热台焊接。不过板子为双面贴片&#xff0c;使用加热台只能焊接一面&#xff0c;那就优先焊主芯片那面&#xff0c;并…

分布式链路追踪——Dapper, a Large-Scale Distributed Systems Tracing Infrastructure

要解决的问题 如何记录请求经过多个分布式服务的信息&#xff0c;以便分析问题所在&#xff1f;如何保证这些信息得到完整的追踪&#xff1f;如何尽可能不影响服务性能&#xff1f; 追踪 当用户请求到达前端A&#xff0c;将会发送rpc请求给中间层B、C&#xff1b;B可以立刻作…

End-to-End Object Detection with Transformers

DERT 目标检测 基于卷积神经网络的目标检测回顾DETR对比Swin Transformer摘要检测网络流程DERT网络架构编码器概述解码器概述整体结构object queries的初始化Decoder中的Muiti-Head Self-AttentionDecoder中的Muiti-Head Attention 损失函数解决的问题 基于卷积神经网络的目标检…

使用JavaMail发送邮件时嵌入公司logo图片

使用JavaMail发送邮件时嵌入公司logo图片 第一种方式&#xff1a;img标签和logo图片链接第二种方式&#xff1a;使用img标签和图片base64字符串第三种方式&#xff08;推荐&#xff09;&#xff1a;将logo当做附件一起发送并设置ContentID&#xff0c;再使用img标签&#xff0c…

C++——移动构造和完美转发

1.什么是右值 右值引用是C11的概念&#xff0c;与之对应的是左值引用。 当一个对象被用作右值的时候&#xff0c;用的是对象的值(内容)&#xff1b;当对象被用作左值的时候&#xff0c;用的是对象的身份(在内存当中的位置)。 以上的概念是摘录自《C primer》。 但是这样的概…

【SentenceTransformer系列】计算句子嵌入的概念(01/10)

一、说明 要分清词嵌入和句子嵌入的区别。 句子嵌入是指将句子或文档表示为固定长度的向量的过程&#xff0c;使得向量能够捕获句子的语义和上下文信息。它是自然语言处理 (NLP) 和机器学习中的常见任务&#xff0c;因为它可以帮助对句子之间的关系和相似性进行建模&#xff0c…

接口自动化测试(添加课程接口调试,调试合同上传接口,合同列表查询接口,批量执行)

1、我们把信息截取一下 1.1 添加一个新的请求 1.2 对整个请求进行保存&#xff0c;Ctrl S 2、这一次我们添加的是课程添加接口&#xff0c;以后一个接口完成&#xff0c;之后Ctrl S 就能够保存 2.1 选择方法 2.2 设置请求头&#xff0c;参数数据后期我们通过配置设置就行 3、…

Lua 位和字节

一、位运算 从 Lua 5.3 版本开始&#xff0c;提供了针对数值类型的一组标准位运算符&#xff0c;与算数运算符不同的是&#xff0c;运算符只能用于整型数。 运算符描述&按位与|按位或&#xff5e;按位异或>>逻辑右移<<逻辑左移&#xff5e;&#xff08;一元运…

安全学习DAY17_信息打点-语言框架组件识别

信息打点-WEB打点-语言框架&开发组件 文章目录 信息打点-WEB打点-语言框架&开发组件本节涉及链接&工具本节知识&思维导图基础概念介绍框架&#xff1a;组件&#xff1a;Web架构 对应Web测试手法后端&#xff1a;前端组件&#xff1a;java居多&#xff0c;框架&…