分布式事务专题

1.基础概念

1.1 什么是事务

一系列的活动操作组合在一起,要不全成功,要不全失败;

1.2 本地事务

本地事务一般我们认为是数据库的事务,一般一个应用连接一个数据库进行一系列的crud的操作,因此本地事务也要符合数据库事务的四大特征—ACID:

A(Atomic):原子性,在一个事务当中的所有的操作,要不然全部成功,要不然全部失败;

C(Consistency):一致性,在一个事务操作的前后,数据的一致性都有所保证。比如A向B转账,A扣钱了,B增加了钱;

I(Isolation):隔离性,两个事务之间互相隔离互不干扰。通过配置事务隔离级别可以避免脏读、不可重复读、幻读/虚读;

D(Durability):持久性,事务提交之后数据持久到数据库,且不会回滚;

保证事物的四个特性,是通过锁机制、undolog、redolog日志来实现的;

其中锁机制是保证了隔离性;

undolog叫做回滚日志,为了控制事务的原子性、一致性;

redolog叫做重做日志,为了控制事务的持久性;

1.3 分布式事务

分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统;

分布式事务指的是分布式系统下,各个服务之间通过网络通信完成事务称之为分布式事务,与本地事务无需进行网络通信不同;

1.4 分布式事务场景

1.微服务架构

​ 假如A调用B,A开启了事务,然后调用B系统,B系统执行成功了,但是这个时候网络通信发生了异常,A系统没有收到正常的返回,这个时候A任务没有调用成功,则A回滚了事务,但是B事务成功提交了,就会造成事务的不一致;

​ 简言之:跨jvm进程调用会产生分布式事务;

2.单体系统跨数据库实例

​ 一个单体系统需要连接两个不同的数据库进行交互,假如连接A库处理事务成功,再连接B库进行处理事务,这个时候B库事务处理失败,A库无法回滚;

​ 简言之:跨数据库实例产生分布式事务;

2.分布式事务基础理论

​ 俗话说理论支撑实践,在我们所有的分布式系统当中,先要知道基本的理论,才能根据理论制定出合理的解决方案。而我们分布式事务理论基础是依赖于分布式的基础理论;其中CAP理论、BASE理论是指导我们分布式系统的基础理论架构;

2.1 CAP理论

​ CAP是Consistency、Availability、Partition Tolerance三个单词的缩写,分别表示一致性、可用性、分区容错性;

2.1.1 一致性

所谓一致性表示,在一个分布式系统当中,某个系统集群所有节点在同一时刻,所有的数据保持的都是一致的;

通常在CAP理论当中的一致性指的就是强一致性;也就是说在集群当中,主节点的数据未同步到从节点,如果在同一时刻,有读操作从节点,这个时候如果要满足一致性就必须返回错误信息!!!

2.1.2 可用性

所谓可用性,指的就是在任何时刻,系统都能响应给客户端数据,无论是旧数据还是默认数据,总之就是系统有正确的响应信息;这就和我们一致性有所冲突,一致性要求必须在数据相同的情况下才能给正确响应信息;

这就可以说明!!!可用性和一致性是不可能共存的!

2.1.3 分区容错性

所谓分区容错性,指的就是在一个系统的集群当中,其中有一个节点挂掉之后,服务整体对外还是可以提供服务的能力,这个一般的做法就是有多个从节点,当主节点挂掉之后从节点顶上,从节点挂掉之后另一个从节点顶上,来保证整体的服务的对外提供服务的能力;

通常来说,在分布式系统的情况下我们的分区容错性一定是要满足的!

2.1.4 如何取舍

分布式系统情况下分区容错性一定满足后,同时一致性和可用性又不能同时共存,所以说CAP三个特性不能三者同时共存!

这就可以看出来在分布式系统中,CAP理论指导,只有两种组合方式AP模型和CP模型;

CP模型:保证强一致性和分区容错性,其中最典型的代表就是我们的Zookeeper,保证集群当中所有的节点必须是可通信的才能提供服务;这样保证了我们的可用性但是大大降低了效率,但是作为注册中心来说,保证可用性又是很关键的;

AP模型:保证了可用性和分区容错性,这也是我们大多数分布式系统采用的方案,舍弃强一致性,保证最终一致性;

而我们现在的SpringCloud Alibab中的Nacos可以作为注册中心+配置中心一起来使用,而我们的Nacos即支持了CP模型也支持了AP模型,这个就需要我们根据具体的业务来定,如果可以接受一定时间的不一致我们就用AP模型,反之则选择CP模型;

2.2 BASE理论

BASE是,Basiclly Avaliable、Soft state、Eventual consistency,基本可用、软状态、最终一致性三个单词的缩写;可以看作BASE理论是对AP模型的一个扩展,通过牺牲强一致性、采用最终一致性、达到基本可用性一种理论;如果采用BASE理论来满足事务,我们通常来说称之为柔性事务;

基本可用:比如说在流量冲击的时间段,系统的核心模块保证是可用的,允许部分非绝对核心的业务出现短暂的业务限流或者损失;

软状态:允许系统中存在中间状态,这个中间状态不影响正常使用,待数据一致性之后改为我们所需要的状态;

最终一致性:运行分布式系统在一段时间范围内数据不一致,但是在最后所有的节点数据最终都能到达一致;

3.分布式事务解决方案之2PC

3.1 什么是2PC

2PC其中,2代表两个阶段、P代表Prepare phase准备阶段、C代表Commit phase提交阶段;2PC又叫做两阶段提交协议,常见的技术解决方案有Seata的;

1.概念

在2PC两阶段提交协议中,需要两个角色,一个角色叫做事务管理器,一个角色叫做事务参与者,事务管理器负责决策整个分布式事务的提交和回滚,事务参与者则只负责自己事物的提交和回滚。

2.关系型数据库中2PC的流程

在Mysql和Oracle的关系型数据库中支持2PC两阶段提交协议,其流程如下:
准备阶段(Prepare phase):事务管理器给事务参与者下达Prepare的消息,事务参与者开始执行本地事务,并写本地的undolog回滚日志和redolog重写日志,此时事务并没有提交;

提交阶段(Commit phase):事务参与者分别向事务管理者回调成功或者失败的消息;如果事务管理器收到了所有的事务参与者的成功回调,则事务管理器向每个事务参与者发送Commit的消息;反之如果有一方参与者失败,则整体由事务管理者再次发送回滚指令;当执行完事务管理者的回滚or提交的指令之后,此时释放掉数据库的锁资源;

3.2 Seata方案

1.概念

Seata是一款阿里巴巴开源Spring Cloud Alibaba其中款针对于分布式事务的解决方案的框架,其中提供了:AT(也就是2PC)、TCC、XA、SAGA的事物模式;Seata框架的开源解决了传统2PC解决方案中需要完全依赖于数据库的XA模式,它以对业务0侵入的方式来解决了分布式系统在处理事务中的问题;同时他的性能较传统的2PC解决方案要高;他的开源官方网站:http://seata.io/zh-cn/docs/overview/what-is-seata.html,快速使用查看官网;

2.架构组成

以下为他的方案架构图,其中我们需要明确几个名词概念:

TC(Transaction Coordinator):事务协调器,他是独立的中间件需要独立部署运行,其作用是用于维护全局事务的运行状态,接收事务管理器下发的全局事务的提交或者回滚的指令,并且与资源管理器RM协调各个分支事务的提交和回滚

TM(Transaction Manager):事务管理器,他需要嵌入到程序当中(往往在程序中需要引入对应相关的jar包),由TM来负责下发开启全局事务、提交全局事务、回滚全局事务的指令;

RM(Resuorce Manager):资源管理器,或者叫做分支管理器,其实就是管理各个分支事务的提交或回滚,主要是接受TC事务协调器的指令分配;

在这里插入图片描述

3.流程解析

所有的TM、RM都需要先向第三方中间件TC进行通信注册,之后按照以下流程进行交互:

A:服务Business作为全局事务的开启者也就是事务管理者TM,向TC注册一个全局事务,全局事务创建成功返回给TM全局事务XID;

B:TM分别网络调用Sotck服务、Order服务,并且携带XID,这时两者作为RM的身份分别向TC进行分支事务注册,TC将该分支事务纳入到全局事务XID下面;

C:RM资源管理器分别执行自己本地事务,并且在自己的undo-log表中记录下来一条事务日志,执行完成后提交事务,并且通知调用者执行成功;

D:当TM收到所有服务的成功返回之后,通知TC全局提交事务;

E:TC收到了TM的全局提交事务之后,分别向RM协调提交事务,此时各个RM收到提交指令之后,删除undo-log中的事务日志;

F:如果TM有异常调用,则通知TC进行全局回滚,此时,各个RM接到TC的回滚指令之后,将对应的undo-log中的数据提取出来之后进行执行来保证数据回滚;

4.分布式事务解决方案之TCC

TCC:try-comfirm-cancel;常见的技术解决方案有Hmily、seata的TCC模式(跟他的AT模式保持对比);

4.1 概念

什么是TCC事务,我们需要首先明确TCC分别代表什么意思:try、confirm、cancel(尝试、确定、取消);我们可以粗暴的理解为在每个阶段都由开发者自行去编写相应的逻辑,但是try阶段的逻辑和cancel的逻辑一定是相反的;

其中try阶段:是为了检查资源和资源的预留,可以简单的理解为检查服务是否可用,以及预留出来接下来需要操作的数据是否满足范围;

confirm阶段:在此阶段,是为了将try阶段所做的操作做一个最终的确认,可能是执行计算也可能是进行最终的确认完成流程;

cancel阶段:在此阶段,实现了与try阶段相反的业务逻辑,来满足在全局事务失败的时候进行回滚的操作;

4.2 TCC实现时可能会遇到的问题

在实现TCC时,会遇到如三个问题:接口幂等问题、空回滚问题、悬挂问题;

幂等:因为我们在分布式系统当中,每个阶段都有可能因为网络通信导致接口失败,此时系统会进行重试操作,如果不做好借口幂等会造成数据的错乱;最好的解决方案我们需要记录TCC事务操作记录,来记录每一次的操作状态,如果执行过之后就过滤掉;

空回滚:造成空回滚的原因是在于cancel阶段的问题,比如try阶段对系统A操作完了,此时对B系统进行try操作,此时如果超时了,则整体事务都需要回滚,但是B系统并未执行try阶段,造成了空回滚问题;解决方案也是使用事务记录表,在执行分支事务的cancel阶段的时候先判断是否执行过try,如果未执行则过滤此操作;

悬挂:造成悬挂问题的主要原因是在try阶段,举例说明:try阶段先调用A系统成功,再调用B系统,此时调用B系统超时,全局事务进行cancel操作,但是B系统此时网络恢复之后继续执行了try操作,就造成了try操作的数据一直不能够cancel或者commit,一直被悬挂起来无法得到处理。解决方案:采用事务记录表,在每次进行try之前,先判断当前分支事务未进行过cancel操作即可;

4.3 TCC的优缺点

优点:性能很高,不会像2PC模式一样需要进行全局事务的锁竞争;数据会得到最终一致性的保障,因为我们每次的针对于事务的操作都有相关的日志记录;

缺点:需要程序针对于某项具体的业务进行编码,在tcc的每个阶段都需要相关的逻辑进行处理,与业务耦合度极高;

5.分布式事务解决方案之可靠消息最终一致性

5.1 概念

所谓可靠消息最终一致性指的是,全局事务的发起方在完成自己的事务之后将消息抛出来,然后由下游的系统进行消费并且提交事务成功。这个方案强调的是事务的最终一致性;

5.2 可靠消息实现时会遇到的问题

需要解决的问题如下:

1.本地事务与发送消息的原子性问题:

这里就需要保证生产者发送消息和事务之间的关系,我们一般称之为事务消息,也就是说我们需要保证本地事务提交成功和发送消息到中间件一起成功,如果失败则一起失败;

这里的解决方案

方案一:

我们可以采用RocketMQ的半事务消息的机制:生产者向broker投递一条半事务消息,broker返回生产者ack确认机制,这个时候生产者执行自己的本地事务,成功或失败都像broker进行二次确认,如果长时间不向broker发送本条本事务消息的话,broker主动过来查询生产者事务的状态来进行判断是提交还是回滚。

在这里插入图片描述

方案二:

或者我们也可以采取本地事务表+spring事务管理的Aftercommit的机制来完成,即先由生产者来完成自己本地事务的处理,然后在提交完事务之后,再将本条消息投递到broker,并且记录消息日志,收到broker的返回之后则抛出成功,如果没有收到返回的会则认为投递消息失败,这个时候我们可以加入机器人提醒,来让开发者介入排查并回滚相应的错误数据;

2.事物消费方消费事务的可靠性和幂等性:

这里存在的问题在于,消息重复消费保证幂等的问题;这里的解决方案很简单,可以使用唯一的业务ID来进行区分;

同时还存在消费方在消费消息的时候,假如由于消费方的故障或者重启之后,正在消费的消息再重启之后依然可以重新进行消费处理;这里我们就可以使用mq的ack机制,只有当顺利消费完成之后,才返回给broker一个ack消费完成的信号;

6.分布式事务解决方案之最大努力通知型事务

6.1 概念

最大努力通知型事务,指的是被调用系统,尽自己最大可能来通知调用系统其事务执行的状态。举个例子来说,我们都对接过微信支付或者支部宝支付,微信和支付宝支付相应时间都很久,我们的调用系统可能需要等待支付宝的回调来通知我们是成功还是失败,这个时候支付宝不一定能回调成功,但是他还提供了查询支付状态的接口来供调用系统查询,尽了自己最大努力的来通知上游系统本次调用的状态;

通过上述方案可以看出最大努力型通知方案的目标:发起通知的一方系统,一定经过自己最大努力来告诉被通知方此次事务的结果

6.2 方案

最大努力型通知方案主要涉及到两个逻辑的处理:

1.有一定的消息重复通知的机制:要不然采用消息重复通知,要不然保证自己接口的重试机制;

2.消息的校对机制:如果一定时间都没有通知到,要提供一定的接口来供上游系统来进行查询;

6.3 最大努力通知和可靠消息最终一致方案对比

角色不同:可靠消息最终一致是需要保证发起调用的一方将消息可靠的投递到消息队列并且下游系统能够消费到保证事务的最终一致性;而最大努力通知事务,是由被调用方在处理完自己复杂的逻辑之后,由自己来确保本次调用的结果可以主动甚至被动的被调用者接收到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值