分布式事务的解决思路与方案

导航

  • 一、事务的种类与场景
  • 二、分布式事务解决方案
    • 2.1 全局事务
    • 2.2 可靠消息事务
    • 2.3 最大努力通知
    • 2.4 TCC 事务
  • 三、TCC 模式常见问题
    • 3.1 二阶段幂等
    • 3.2 空回滚
    • 3.3 资源悬挂

一、事务的种类与场景

本地事务实际上就是指数据库的事务,参考《MySQL —— 事务与隔离级别总结》

分布式事务指的是在分布式环境下,由多个本地事务组成,多个系统之间如何保证事务之间的原子性、一致性等问题。例如多个系统访问同一个数据库,多个系统访问多个数据库,等等这些场景,都数据分布式事务的讨论范围。

二、分布式事务解决方案

介绍四个业界应用比较广泛的分布式解决方案:全局事务、可靠消息服务、最大努力通知、TCC事务(补偿型事务)。

2.1 全局事务

全局事务基于DTP 模型实现,这是由X/Open 组织提出的一种分布式事务模型,全称为“分布式事务处理参考模型”。

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

AP:Application 应用系统
TM:Transaction Manager 事务管理器
RM:Resource Manager 资源管理器

在 DTP 模型中,整个系统的事务分为两个阶段,即 2PC(2 Phrase Commit):

1、准备阶段:也可以叫表决阶段或投票阶段。TM 向 各个 AP 发送准备命令,并告诉各本地事务即将提交事务。TM同步等待参与者的响应。此阶段各本地事务已经完成了事务逻辑,就差一步提交操作。
2、提交阶段:TM 根据响应结果,决定发送提交或回滚命令。若都准备成功,则提交事务;但只要有一个返回失败,就全部回滚。

在这里插入图片描述
全局事务的优缺点:

优点:由于是同步阻塞协议,因此可以保证数据的强一致性。资源管理器本身就是数据库,实现不需要增加太多的代码逻辑,实现成本低。流程简单。
缺点
1、单点故障问题:TM 是全局事务的协调者、管理者,绝不能出现单点故障问题。
2、同步阻塞:增加了资源阻塞时间,可能存在死锁的风险,需要增加超时机制。
3、一致性问题:二阶段提交可能存在失败的情况,导致数据不一致。

总之,该模型是旨在保证强一致性的全局事务模型,但由于其模型仍然简单粗糙,在实际生产中,还需要进一步扩展和细化。

2.2 可靠消息事务

基于可靠消息服务的方案是通过消息中间件保证上、下游应用数据操作的一致性。基本可以理解为就是 RocketMQ提供的事务消息,参考《Spring Cloud —— RocketMQ 的消息类型》

假设有A和B两个系统,分别可以处理任务A和任务B。此时存在一个业务流程,需要将任务A和任务B在同一个事务中处理,就可以使用消息中间件来实现这种分布式事务。
在这里插入图片描述

2.3 最大努力通知

最大努力通知也被称为定期校对,其实是对可靠消息事务方案的进一步优化。它引入了本地消息表来记录错误消息,然后加入失败消息的定期校对功能,来进一步保证消息会被下游系统消费。

这种方案由于本身需要引入许多额外的补偿结构,如本地消息表、失败消息表、定期校对者等等,增加了业务耦合度,提高了实现复杂度,因此在业界并不是特别流行,但不得不说的确是增加了系统事务的安全性降低了事故风险。
在这里插入图片描述
第一步:消息由A系统投递到中间件

1、处理业务的同一事务中,向本地消息表中写入一条记录
2、准备专门的消息发送者,轮询本地消息表,将需要发送的(未发送的或失败的)事务消息发送到中间件

第二步:消息由中间件投递到B系统

1、消息中间件收到消息后负责将该消息同步投递到下游系统,并触发下游系统的任务执行
2、当下游系统处理成功后,向消息中间件反馈确认应答,消息中间件便可以将该消息删除,表示该事务完成
3、如果投递失败,增加重试机制,对重试失败的,写入错误消息表
4、消息中间件需要提供失败消息的回查接口,下游系统会定期查询失败消息,自行消费。

优点:一种非常经典的分布式事务解决方案,最大限度保证最终一致性。
缺点:消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

2.4 TCC 事务

TCC 即为 Try Confirm Cancel,它属于补偿型分布式事务,业务层面的分布式事务。其中:

Try:指的是预留,即资源的预留和锁定。
Confirm:确认,其实就是真正的执行提交。
Cancel:撤销,就是回滚、撤销锁定动作。

同样,TCC模型也有一个全局的管理者或协调者角色,用来记录TCC全局事务状态,并提交或回滚事务。

TCC模型的难点在于业务上的定义,对每一个操作都需要定义三个动作分别对应 try-confirm-cancel例如,预留操作,需要明确预留或锁定的业务资源。因此TCC是业务耦合型分布式事务,需要根据特定的场景和业务逻辑来设计相应的操作。另外,确认或撤销操作可能需要重试,因此需要保证操作的幂等。

TCC相较于2PC、3PC,其优点在于可以跨数据库跨业务来实现事务,但缺点也显而易见,就是开发量大,业务耦合度高。

TCC 两阶段提交与 XA 两阶段提交的区别:

XA 是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,会一直持有资源的锁。
TCC 是业务层面的分布式事务,最终一致性,不会一直持有资源的锁。

三、TCC 模式常见问题

TCC分布式事务模式其实属于2PC的一种。其本身仍然存在一些绕不开的问题。

3.1 二阶段幂等

由于网络抖动,分布式事务框架可能会重复调用同一分布式事务中的一个分支事务的二阶段方法(comfirm或cancel)。
所以分支事务的二阶段接口必须要保证幂等性,否则会产生资源的重复使用或重复释放从而影响业务。
对于幂等类型的问题,通常的手段是引入幂等查询。例如,可以通过增加一张事务状态表,包含如下几个关键字段:

1.主事务id
2.分支事务id,与主事务id作为联合主键,唯一标识一笔分支事务。
3.分支事务状态:init(1),confirmed(2),rollbacked(3)

幂等记录的插入时机是参与者的Try 方法,此时的分支事务状态会被初始化为 init。然后当二阶段的 comfirm/canel 执行时会将其状态置为 comfirmed/rollbacked。
当TC重复调用二阶段接口时,参与者会先获取事务状态控制表对应的记录查看其事务状态。如果状态已为终态(confirmed或rollbacked),则直接将结果返回给TC,帮助其推进分布式事务,时序图如下:
在这里插入图片描述

3.2 空回滚

空回滚指的是,在未收到 Try 请求的情况下收到 Cancel 请求

如果不对空回滚加以防范的话,可能会造成资源的无效释放,即在没有预留资源的情况下就释放资源,造成故障。

针对空回滚,使用事务状态控制表同样有效。

当 Try 方法被成功执行后,会插入一条分支事务记录,当后续二阶段的 Cancel 方法执行时,如果记录存在且状态为 INIT,就表示一阶段已成功执行,可以正常执行回滚,释放预留资源;如果记录不存在则表示一阶段未执行,本次为空回滚,不释放任何资源。

一般情况下,是应用是需要允许空回滚的。

3.3 资源悬挂

资源悬挂,意思是一阶段Try 由于网络超时或阻塞等原因,在二阶段Cancel(Try超时事务管理器要Cancel全局事务)之后执行,即 Cancel --> Try,造成服务或资源悬挂。

可以看到,资源悬挂的前提是空回滚。因为一阶段Try超时,事务管理器必须执行回滚操作,这就造成了参与者一定会先收到 Cancel ,即空回滚。

视实际业务场景而定,一般会允许空回滚的情况,但要避免悬挂。可以在空回滚后,向事务状态控制表中插入一条 状态为 ROLLBACKED 的分支事务记录,然后在 Try 的时候要增加对幂等的处理(可以依赖于数据库的唯一约束),这样,由于网络原因而超时的 Try 请求就会自动失败,从而放弃调本次TCC事务。

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

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

相关文章

css3 下边框缓缓划过_干货来袭!web前端开发工程师必看之如何使用CSS3实现瀑布流效果?...

首先,我们来看一下什么是瀑布流布局效果,比如电商网站 蘑菇街原理图:在一个大盒子里,放置多个小盒子,小盒子的大小可以不一致,长短不一样,呈现一种瀑布流的效果。使用CSS3S实现只需要如下4步:1. 准备图片素材2. 书写相应HTML结构3…

Spring Cloud Alibaba —— Seata 分布式事务框架

导航一、Seata 介绍二、Seata 的工作原理2.1 三个角色2.2 工作流程三、Seata AT 工作机制3.1 一阶段3.2 二阶段四、案例演示(待补充)一、Seata 介绍 官网:Seata 官网 Seata 是2019 年阿里巴巴中间件团队发起的开源项目,其前身是…

云麦体脂秤华为体脂秤_华为、小米和有品体脂秤哪个品牌好?三款智能体脂秤横评结果排行...

如今生活水平的提高,也让更多人开始关注健康问题。由于大部分时间都忙于工作,本身就运动少、体重超标等等。如果长期得不到控制的话,会造成日后脂性肝炎、肝纤维化、肝癌,想想都可怕,在意识到这样的严重性,…

Guava常用工具类的使用

导航引言一、Lists.partition引言 本文用于记录工作中常用到的 Guava 工具类的使用。 依赖引入&#xff1a; <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version></depend…

idea 调用c#接口_Dubbo 接口测试方法

一.直接通telnet然后用dubbo协议调用方法&#xff08;1&#xff09;在项目的配置文件中可以看到dubbo.protocol.port10022说明dubbo对外暴漏的端口为10022&#xff0c;直接用telnet访问此端口。telnet lcoalhost 10022然后就能看到说明连接成功。用ls查看服务查看服务下有那些方…

MySQL 面试问答

导航一、什么是回表查询&#xff1f;如何避免回表查询&#xff1f;二、为什么MySQL建议使用自增主键&#xff1f;什么是代理主键、业务主键&#xff1f;三、为什么MySQL建议单表不超过2000W数据&#xff1f;四、MySQL自增id用完了怎么办&#xff1f;五、MySQL自增主键是连续的吗…

tcs标准编写软件_【公益培训】知你所需 | 标准编写格式及TCS模板应用线上公益培训...

企业标准编写的水平及TCS工具使用的能力是实施企业标准化工作的基础。TCS标准编写软件是辅助标准编写的工具性软件&#xff0c;方便标准编写人员快捷准确的编写标准草案&#xff0c;有效提升标准供给质量。为贯彻落实疫情防控和助力企业复工复产工作&#xff0c;山东标准化协会…

Linux进阶之路——常用命令总结

一、帮助命令 help man type区分内建、外建命令 【扩展】关于内建命令与外建命令。 内建命令属于shell程序的一部分&#xff0c;包含一些比较简单的Linux命令。这些命令被写在/bin/bash 文件的 builtins 里面&#xff0c;由shell程序识别并在shell程序内部完成运行。通常在Li…

bios设置 联想m8000t_怎么进bios设置硬盘启动顺序

操作说明&#xff1a;1、不同电脑进BIOS按键不一样&#xff0c;常见的有del、F1、F2、Esc、enter、F8、F9等2、在电脑启动时&#xff0c;不停按Del、F2等按键会进入BIOS设置界面&#xff0c;开机按哪个键进BIOS设置BIOS类型一&#xff1a;CMOS Setup Utility1、启动时按Del进入…

MySQL 基础 ————事务与隔离级别总结

引言 在处理并发读或写时&#xff0c;可以通过实现一个由两种类型的锁组成的锁系统来解决问题&#xff1a; 共享锁&#xff08;shared lock&#xff09;和排它锁&#xff08;exclusive lock&#xff09;&#xff0c;也叫读锁&#xff08;read lock&#xff09;和写锁&#xff0…

32f407tim4时钟源频率_慎重选择时钟发生器,别让这俩指标影响你的ADC 「图片」...

系统设计师通常侧重于为应用选择最合适的数据转换器&#xff0c;在向数据转换器提供输入的时钟发生器件的选择上往往少有考虑。然而&#xff0c;如果不慎重考虑时钟发生器的相位噪声和抖动性能&#xff0c;数据转换器动态范围和线性度性能可能受到严重的影响。系统考虑因素采用…

Spring —— IoC 容器详解

引言 本篇博客总结自官网的《The IoC Container》&#xff0c;其中会结合王富强老师的《Spring揭秘》融入自己的语言和理解&#xff0c;争取通过这一篇文章彻底扫除spring IOC的盲区。 本文介绍什么是 IoC 容器&#xff0c;什么是 Bean&#xff0c;依赖&#xff0c;Bean Defi…

nvidia控制面板点了没反应win7_win7系统Nvidia控制面板怎么设置?

许多用户不知道Nvidia控制面板怎么设置?那么Nvidia控制面板如何设置呢?其实设置的方法很简单。接下来&#xff0c;小编就把Nvidia控制面板设置的方法告诉大家。1、首先在桌面右键点击选择NVIDIA控制面板。2、显卡的设置性能肯定是要高好了&#xff0c;所以在性能设置方面&…

切割 字符串_web前端如何使用字符串

一、字符串概述定义&#xff1a;字符串就是用单引号或者双引号包裹起来的&#xff0c;零个或多个排列在一起的字符。例如&#xff1a;’javascript‘, “”, “345” , ’9-11a$‘, “xiao_yuanLian”嵌套&#xff1a;字符串可以嵌套。在单引号包裹的字符串内部&#xff0c;应该…

卡尔曼_卡尔曼滤波最完整公式推导

卡尔曼滤波是一种利用线性系统状态方程&#xff0c;通过系统输入输出观测数据&#xff0c;对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响&#xff0c;所以最优估计也可看作是滤波过程。上面一段话来自百度百科&#xff0c;其实最核心的意思就是卡…

Redis 缓存实战——缓存、数据库一致性问题分析与解决方案

引言 缓存与数据库一致性的问题自从出现了缓存概念后就一直被提及&#xff0c;它是一个缓存方案的先天缺陷&#xff0c;只要存在缓存&#xff0c;就势必会讨论缓存与数据库一致性的问题。 一致性问题还广泛存在于各种分布式存储场景中&#xff0c;如主从一致性等等。 本篇博…

基于计算思维的python程序设计王彬丽期末考试题库_基于计算思维的程序设计类课程教学实践...

基于计算思维的程序设计类课程教学实践滕剑锋王玉锋王猛刘二林【摘要】摘要很多专业开设了程序设计类课程。如何在该课程教学中培养学生的创新能力是大家普遍考虑的问题。计算思维的提出对于解决该问题具有重要的指导意义。在此背景下&#xff0c;我们针对程序设计类课程的教学…

Java 多线程 —— AQS 详解

引言 AQS 是AbstractQuenedSynchronizer 的缩写&#xff0c;抽象的队列式同步器&#xff0c;它是除了java自带的synchronized关键字之外的锁机制。是 JUC 下的重要组件。 相关产物有&#xff1a;ReentrantLock、CountDownLatch、Semaphore、ReadWriteLock等。 一、AQS的设计…

的主机名_如何在Mac 上更改电脑的名称或本地局域网主机名?

我们知道&#xff0c;一台电脑有其设定的具体名称&#xff0c;电脑的名称和本地主机名用于在本地网络上识别您的电脑。当我们需要自定义电脑名称或本地局域网主机名时&#xff0c;则需要对其进行更改。那我们该如何更改呢&#xff1f;有需要的小伙伴们快和小编一起来看看吧~更改…

Java常用设计模式——观察者模式

导航一、行为描述二、角色关系三、代码示例一、行为描述 观察者会观察特定对象的状态变化&#xff0c;一旦状态有所变化或产生特定条件&#xff0c;被观察对象会通知给观察者&#xff0c; 而观察者则会依据通知信息采取特定处理措施。 举个例子&#xff0c;公司接到了一个大项…