分布式事务架构的五大演进

文章目录

一、前言

分布式事务的典型例子就是银行转账系统,A给B转账100
如果是一个单体架构一个数据库,直接用数据库事务就可以保证了;
如果是后端微服务架构 + mysql数据库集群,需要使用分布式事务实现。

事务是数据库特有的概念,分布式事务最初起源于处理多个数据库之间的数据一致性问题,但随着IT技术的高速发展,大型系统中逐渐使用SOA服务化接口替换直接对数据库操作,所以如何保证各个SOA服务之间的数据一致性也被划分到分布式事务的范畴
对于多数据库的数据一致性问题,使用 两段式/三段式 处理;
对于SOA服务的数据一致性问题,使用TCC编程模式处理。两种是不同的。

二、银行转账例子:从事务到分布式事务

在支付、交易、订单等强一致性系统中,我们需要使用分布式事务来保证各个数据库或各个系统之间的数据一致性。

银行转账的例子是数据库事务保证数据一致性最常用的(单个数据库就事务,多个数据库就分布式事务):程序员小张向女友小丽转账100人民币,转账过程是:先扣除小张100元,再为小丽的账户添加100元。

理论要求:如果在转帐过程中,扣款操作和打款操作要么同时执行,要么同时都不执行,我们就认为转帐过程保证了数据一致性。

实践上,如果我们不使用分布式来保证转账过程中数据的一致性,就有可能出现小张账户上的钱被扣除,而小丽账户上的钱却没被添加的情况,造成错误。

事务是数据库特有的概念,分布式事务最初起源于处理多个数据库之间的数据一致性问题,但随着IT技术的高速发展,大型系统中逐渐使用SOA服务化接口替换直接对数据库操作,所以如何保证各个SOA服务之间的数据一致性也被划分到分布式事务的范畴

本文将从一个最为简单的交易系统出发,由浅入深地讲述分布式事务架构的演进过程,希望对大家理解分布式事物架构有所帮助。

三、五种事务演变

3.1 单数据库事务(简单,一个事务包一层就处理了)

先来看看我们需要实现的交易系统:游戏中的玩家使用金币购买道具,交易系统需要负责扣除玩家金币并为玩家添加道具。

我们把交易系统的一次交易流程归纳为两步:
(1)扣除玩家金币
(2)为玩家添加道具

需求并不复杂,我们为金币系统在数据库中添加金币表,为道具系统在数据库中添加道具表,扣除金币与添加道具的操作只需执行相应的SQL即可。

这里我们假设金币表与道具表都在同一个数据库中,于是可以简单地使用单数据库事务来保证数据的一致性。

下面是使用单数据库事务进行一次正常交易的时序图:

在这里插入图片描述

对于上图的解释:
BEGIN TRANSACTION
sql语句:扣除金币;
sql语句:添加道具;
END TRANSACTION;
解释:因为两条sql语句被一个事务包裹,单数据库下,要么一起执行,要么一起不执行。
小结:从事务到分布式事务:
单个数据库,使用数据库Innodb自带的事务机制,可以实现多条sql语句,要么一起执行,要么一起不执行;多个数据库,就没有数据库自带的事务机制了,就要使用分布式事务机制。

对于上图的解释:
在步骤[2]执行SQL扣除金币时出现异常,回滚事务即可保证数据一致
在步骤[4]执行SQL添加道具时出现异常,回滚事务即可保证数据一致
在步骤[6]提交事务时出现异常,回滚事务即可保证数据一致
所以,单数据库情况下,使用数据库自带的Transaction事务机制(具体地,后端使用@Transaction注解或者sql语句中使用START TRANSACTION),可以100%保证数据一致性,只需没有异常提交事务而出现异常回滚事务即可。

3.2 基于后置提交的多数据库事务

3.2.1 用户数增多,mysql集群引入

用户数增多,mysql集群引入
随着玩家数量激增,金币表与道具表的总行数与访问量都急剧扩大,单台数据库不足以支撑起这两张表的读写请求,这时将金币表与道具表放在不同的数据库中是个不错的选择。
这里我们假设金币表被放入了金币数据库中,而道具表被放入了道具数据库中,通常我们将这种按不同业务拆分数据库的方式称之为数据库垂直拆分。
数据库垂直拆分能大大缓解数据库的压力问题,但多个数据库的存在意味着我们不能通过简单的单数据库事务来保证数据的一致性,如何保证多数据库之间数据的一致性,也就是分布式事务需要解决的问题。

3.2.2 还是使用 执行-提交 模式(一句数据不一致)

还是使用 执行-提交 模式
对于我们的交易系统,先不考虑多数据库之间的数据一致性问题,简单的交易流程为:
在这里插入图片描述
解释上图,正常情况下,上面的流程不会产生数据一致性问题,但是
(1)如果在步骤[7]执行SQL添加道具时出现异常,由于扣除金币的事务已经在步骤[5]提交无法回滚,就会出现扣除玩家金币后没有为玩家添加道具的数据不一致情况。
小结:上面问题产生的原因其实是过早地向金币数据库提交事务,所以我们可以采取后置提交事务策略来解决此问题,即先在金币数据库与道具数据库上执行SQL,最后再提交金币数据库与道具数据库上的事务,这样当执行SQL出现异常时,我们就能通过同时回滚两个数据库上事务的方式,来保证数据一致性。

3.2.3 使用先全部执行完,再全部提交,后置事务提交(先全部执行,然后全部提交,四句中一句数据不一致)

使用先全部执行完,再全部提交,后置事务提交
下面是使用后置提交事务进行一次正常交易的时序图:
在这里插入图片描述
对于上图的解释:
在步骤[3]执行SQL扣除金币时出现异常,回滚金币数据库上的事务即可保证数据一致
在步骤[5]执行SQL添加道具时出现异常,同时回滚金币数据库与道具数据库上的事务即可保证数据一致
在步骤[7]提交扣除金币事务时出现异常,同时回滚金币数据库与道具数据库上的事务即可保证数据一致
在步骤[9]提交添加道具事务时出现异常,由于扣除金币事务已提交无法回滚,会出现扣除玩家金币后没有为玩家添加道具的数据不一致情况
小结:使用后置提交事务的策略,虽然能避免SQL执行异常导致的数据不一致,但在最后提交事务遇到异常时却无能为力,所以我们需要引入新的事务提交方式。

3.3 基于两段提交的多数据事务(略,6种分布式中讲过了)

两段式事务提交的引入
由于传统方式的事务提交无法完美保证多个数据库之间数据的一致,于是计算机科学家们引入了两段式事务提交(这是目前多数据库分布式事务的通用解决方案)。
所谓两段式事务提交指的是在执行提交commit操作前,添加预提交prepare操作,其中预提交操作执行了传统意义上提交操作的大部分工作,我们可以简单地认为只要预提交prepare操作成功,后续的提交commit操作一定会成功。

实践:两段式事务提交
我们将购买道具的交易流程改为两段提交,时序图如下:
在这里插入图片描述
解释上图:我们在真正提交事务之前采用了预提交事务,预提交是一个很重的操作,一旦抛出异常,我们回滚事务即可,但预提交一旦成功,后续的提交操作则非常轻量,几乎可以认为不会出错,这样我们就使用两段提交保证了多个数据库之间数据的一致性。

两段式事务也就是著名的XA事务,XA是由X/Open组织提出的分布式事务的规范,也是目前使用最为广泛的多数据库分布式事务规范。
一般情况下,我们在使用XA规范编写多数据库分布式事务代码时,不用自己去实现两段提交代码,而是使用atomikos等开源的分布式事务工具。
下面是一个使用atomikos实现简单分布式事务(XA事务)的源码:
github.com/liangyanghe/xa-transaction-demo

3.4 TCC 多数据库事务

3.4.1 从金币数据库、道具数据库到金币服务、道具服务(记住图,直接调用)

从金币数据库、道具数据库到金币服务、道具服务
之前我们的交易系统在进行购买道具时,都是直接操作金币表与道具表,下面我们对交易系统的架构进行升级:
将与金币相关的操作独立成一套金币服务,将与道具相关的操作独立成一套道具服务,交易系统在扣除金币与添加道具时,不再直接操作数据库表,而是调用相应服务的SOA接口。
基于SOA接口的最简交易时序图如下:
在这里插入图片描述
注意,这里将之前的金币数据库、道具数据库变成了金币服务、道具服务,这样,之前对数据库的操作变成了对SOA服务的操作。

3.4.2 接上面,调用SOA服务的数据一致性问题,使用TCC编程模式解决

金手指:调用SOA服务的数据一致性问题,使用TCC编程模式解决
我们考虑在步骤[3]调用SOA接口添加道具时出现异常,由于之前已经调用SOA接口扣除金币成功,于是就会出现扣除玩家金币后,没有为玩家添加道具的不一致情况。
为保证各个SOA服务之间的数据一致性,我们需要设计基于SOA接口的分布式事务。目前比较流行的SOA分布式事务解决方案是TCC事务,TCC事务的全称为:Try-Confirm/Cancel,翻译成中文即:尝试、确定、取消。
简单来说,TCC事务是一种编程模式,如果SOA接口的提供者与调用者都遵从TCC编程模式,那么就能最大限度的保证数据一致性。

3.4.3 接上面,TCC模式的三个接口(先全部try,再全称commit,四种情况中一种无法满足)

金手指:什么是TCC编程模式?
回答:第一,TCC编程模式将原来的一个接口变成了三个接口
1、非TCC模式的扣除金币操作,接口提供者只需要提供一个SOA接口即可,接口的作用就是扣除金币。
2、TCC模式的扣除金币操作,接口提供者针对扣除金币这一操作需要提供三个SOA接口:
(1)扣除金币Try接口,尝试扣除金币,这里只是锁定玩家账户中需要被扣除的金币,并没有真正扣除金币,类似于信用卡的预授权;假设玩家账户中100金币,调用该接口锁定60金币后,锁定的金币不能再被使用,玩家账户中还有40金币可用
(2)扣除金币Confirm接口,确定扣除金币,这里将真正扣除玩家账户中被锁定的金币,类似于信用卡的确定预授权完成刷卡
(3)扣除金币Cancel接口,取消扣除金币,被锁定的金币将返还到玩家的账户中,类似于信用卡的撤销预授权取消刷卡
第二,TCC编程模式下,SOA接口调用者如何使用这三个接口呢?
1、调用者先执行扣除金币Try接口,再去执行其他任务(比如添加道具);
2、当其他任务执行成功,调用者执行扣除金币Confirm接口确认扣除金币;
3、当其他任务执行异常,调用者则执行扣除金币Cancel接口取消扣除金币。

第三,图解TCC模式
这里我们假设添加道具的SOA接口也满足TCC模式,下图是使用TCC事务进行道具购买的时序图:
在这里插入图片描述
解释上图(TCC编程模式如何保证数据一致性)
在步骤[1]调用扣除金币Try接口时出现异常,调用扣除金币Cancel接口即可保证数据一致
在步骤[3]调用添加道具Try接口时出现异常,调用扣除金币Cancel接口与添加道具Cancel接口即可保证数据一致
在步骤[5]调用扣除金币Confirm接口时出现异常,调用扣除金币Cancel接口与添加道具Cancel接口即可保证数据一致
在步骤[7]调用添加道具Confirm接口时出现异常,由于扣除金币操作已经确定不能再取消,所以这里会引发数据不一致
小结:即使我们使用了TCC事务,也无法完美的保证各个SOA服务之间的数据一致性。但是,TCC事务为我们屏蔽了大多数异常导致的数据不一致,同时一般情况下,进行Confirm或Cancel操作时产生异常的概率极小极小,所以对于一些强一致性系统,我们还是会使用TCC事务来保证多个SOA服务之间的数据一致性。

3.5 最终一致性 数据库事务(主功能先全部try,然后confirm,四种情况下一种数据不一致,从功能直接调用,无需使用TCC)

问题提出:TCC事务的性能问题?
标准回答:使用最终一致性数据补偿机制,对于核心服务保证强一致性,对于非核心服务使用 消息队列+定时任务 保证最终一致性。
解释

有了TCC事务,我们能够保证多个SOA服务之间的数据一致性,但是,TCC事务存在不小的性能问题。
为了描述性能问题的产生,我们将交易系统的需求略作修改:游戏中的玩家使用金币购买道具A,系统将自动赠送给玩家道具B,道具C与道具D。
这里我们假设我们到道具服务不支持批量添加道具,而只有基于TCC模式的添加单个道具的接口。
为保证数据一致性,交易系统需要先调用扣除金币Try接口,然后再依次调用添加道具A、B、C、D的Try接口,最后再依次调用对应的Confirm接口。
如果这样做,因为TCC事务是先Try再Confirm的模式,接口调用量会翻倍,这在接口调用量小时性能影响并不明显,但上面的需求中我们执行扣除金币,添加道具A、B、C、D共有5个接口调用,翻倍后变为10个(解释:try五个接口,confirm五个接口),系统性能会大大降低。那么是否有既能保证数据一致性,又能保证性能的分布式事务方案?
回答:使用最终一致性数据补偿机制,对于核心服务保证强一致性,对于非核心服务使用 消息队列+定时任务 保证最终一致性,看下面的图。

附:事务一致性划分为两类:强一致性,最终一致性
强一致性事务,请求结束后,数据就已经一致
最终一致性事务,请求结束后,数据没有一致,但一段时间后数据能保持一致
强一致性:其实我们使用的基于后置提交的多数据库事务与TCC事务都属于强一致性事务,使用强一致性事务能保证事务的实时性,但却很难在高并发环境中保证性能。
最终一致性事务:最终一致性事务这几个字看起来很牛逼,但说白了就是异步数据补偿,即在核心流程我们只保证核心数据的实时数据一致性,对于非核心数据,我们通过异步程序来保证数据一致性。
为什么使用最终一致性可以保证TCC编程模式速度快?
由于最终一致性事务引入了异步数据补偿机制,主流程的执行流程被简化(核心服务主流程,非核心服务 消息队列+定时任务),性能自然得到提高。

目前主流触发异步数据补偿的方式有两种:
1、使用消息队列实时触发数据补偿,核心流程在保证核心数据的一致性后,使用消息队列的方式通知异步程序进行数据补偿,这种方式能近乎实时的使数据达到最终一致性,但如果消息队列或异步程序出现异常,数据一致性也将不能保证
2、使用定时任务周期性触发数据补偿,核心流程在保证核心数据的一致性后直接返回,由定时任务周期性触发数据补偿程序,这种方式虽不能像消息队列那样能近乎实时的使数据达到最终一致性,但数据补偿程序出现异常时,我们能比较容易在下个周期对数据进行修复,能最大限度的保证数据的一致性
小结,上面两种异步数据补偿的方式各有利弊,消息队列方式实时性强,但在异常情况下一致性弱,而定时任务方式实时性弱,但在异常情况下一致性强。
其实最优的策略是同时使用消息队列与定时任务触发数据补偿。
正常情况下,我们使用消息队列近乎实时的异步触发数据补偿,能近乎实时的使数据达到最终一致性;
对于那些极少发生的异常,我们使用定时任务周期性的修补数据,按照定时任务的执行周期,周期性的达到最终一致性。

实践:解决TCC事务的性能问题,使用最终一致性数据补偿机制,对于核心服务保证强一致性,对于非核心服务使用 消息队列+定时任务 保证最终一致性。
回到上面的新版交易系统:游戏中的玩家使用金币购买道具A,系统将自动赠送给玩家道具B,道具C与道具D。
下图是使用消息队列实时触发数据补偿实现最终一致性的时序图(如看不清楚可以点击图片放大):
在这里插入图片描述
解释上图,
上图为我们解释了最终一致性是如何使用数据补偿机制(消息队列+定时任务)实现的。
扣除金币,添加道具A、B、C、D,其中,前两个是核心,后三个是非核心,对于核心接口,要保证强一致性,两个先try,然后再confirm,对于非核心服务,没必要在时间上保证强一致性。

解释上图:
使用TCC事务保证了扣除金币与添加道具A数据一致,然后发送赠送消息并结束请求,赠送系统收到消息后负责添加道具B、C、D,最终保证数据一致。
这里如果消息队列或赠送服务出现异常我们的最终一致性将难以保证,所以我们可以再引入一个定时任务,周期性的触发异常数据补偿。
这样我们就实现了一个既能保证最终数据一致,又能保证性能的道具买赠系统。

四、面试金手指

第一,从事务到分布式事务(从第一部分到第二部分)
单个数据库,使用数据库Innodb自带的事务机制,可以实现多条sql语句,要么一起执行,要么一起不执行;多个数据库,就没有数据库自带的事务机制了,就要使用分布式事务机制。

第二,服务取代数据库(第四部分 SOA服务,TCC模式)
事务是数据库特有的概念,分布式事务最初起源于处理多个数据库之间的数据一致性问题,但随着IT技术的高速发展,大型系统中逐渐使用SOA服务化接口替换直接对数据库操作,所以如何保证各个SOA服务之间的数据一致性也被划分到分布式事务的范畴

第三,两段式/三段式 和 TCC编程模式 两种分布式事务的区别(第四部分 SOA服务,TCC模式)
对于多数据库的数据一致性问题,使用 两段式/三段式 处理;
对于SOA服务的数据一致性问题,使用TCC编程模式处理。两种是不同的。

4.1 单数据库事务

对于上图的解释:
在步骤[2]执行SQL扣除金币时出现异常,回滚事务即可保证数据一致
在步骤[4]执行SQL添加道具时出现异常,回滚事务即可保证数据一致
在步骤[6]提交事务时出现异常,回滚事务即可保证数据一致
所以,单数据库情况下,使用数据库自带的Transaction事务机制(具体地,后端使用@Transaction注解或者sql语句中使用START TRANSACTION),可以100%保证数据一致性。

4.2 基于后置提交的多数据库事务

用户数增多,mysql集群代替单台mysql

还是使用 执行-提交 模式
正常情况下,上面的流程不会产生数据一致性问题,但如果在步骤[7]执行SQL添加道具时出现异常,由于扣除金币的事务已经在步骤[5]提交无法回滚,就会出现扣除玩家金币后没有为玩家添加道具的数据不一致情况。
小结:上面问题产生的原因其实是过早地向金币数据库提交事务,所以我们可以采取后置提交事务策略来解决此问题,即先在金币数据库与道具数据库上执行SQL,最后再提交金币数据库与道具数据库上的事务,这样当执行SQL出现异常时,我们就能通过同时回滚两个数据库上事务的方式,来保证数据一致性。

使用先全部执行完,再全部提交,后置事务提交
在步骤[3]执行SQL扣除金币时出现异常,回滚金币数据库上的事务即可保证数据一致
在步骤[5]执行SQL添加道具时出现异常,同时回滚金币数据库与道具数据库上的事务即可保证数据一致
在步骤[7]提交扣除金币事务时出现异常,同时回滚金币数据库与道具数据库上的事务即可保证数据一致
在步骤[9]提交添加道具事务时出现异常,由于扣除金币事务已提交无法回滚,会出现扣除玩家金币后没有为玩家添加道具的数据不一致情况
小结:使用后置提交事务的策略,虽然能避免SQL执行异常导致的数据不一致,但在最后提交事务遇到异常时却无能为力,所以我们需要引入新的事务提交方式。

4.3 基于两段式/三段式提交的多数据库事务

《分布式事务六种实现方式》中讲的很清楚了,略。

4.4 TCC多数据库事务

4.4.1 从金币数据库、道具数据库到金币服务、道具服务

从金币数据库、道具数据库到金币服务、道具服务
之前我们的交易系统在进行购买道具时,都是直接操作金币表与道具表,下面我们对交易系统的架构进行升级:
将与金币相关的操作独立成一套金币服务,将与道具相关的操作独立成一套道具服务,交易系统在扣除金币与添加道具时,不再直接操作数据库表,而是调用相应服务的SOA接口。
基于SOA接口的最简交易时序图如下:
在这里插入图片描述
注意,这里将之前的金币数据库、道具数据库变成了金币服务、道具服务,这样,之前对数据库的操作变成了对SOA服务的操作。

4.4.2 接上面,调用SOA服务的数据一致性问题,使用TCC编程模式解决

金手指:调用SOA服务的数据一致性问题,使用TCC编程模式解决
我们考虑在步骤[3]调用SOA接口添加道具时出现异常,由于之前已经调用SOA接口扣除金币成功,于是就会出现扣除玩家金币后,没有为玩家添加道具的不一致情况。
为保证各个SOA服务之间的数据一致性,我们需要设计基于SOA接口的分布式事务。目前比较流行的SOA分布式事务解决方案是TCC事务,TCC事务的全称为:Try-Confirm/Cancel,翻译成中文即:尝试、确定、取消。
简单来说,TCC事务是一种编程模式,如果SOA接口的提供者与调用者都遵从TCC编程模式,那么就能最大限度的保证数据一致性。

4.4.3 接上面,TCC模式的三个接口

金手指:什么是TCC编程模式?
回答:第一,TCC编程模式将原来的一个接口变成了三个接口
1、非TCC模式的扣除金币操作,接口提供者只需要提供一个SOA接口即可,接口的作用就是扣除金币。
2、TCC模式的扣除金币操作,接口提供者针对扣除金币这一操作需要提供三个SOA接口:
(1)扣除金币Try接口,尝试扣除金币,这里只是锁定玩家账户中需要被扣除的金币,并没有真正扣除金币,类似于信用卡的预授权;假设玩家账户中100金币,调用该接口锁定60金币后,锁定的金币不能再被使用,玩家账户中还有40金币可用
(2)扣除金币Confirm接口,确定扣除金币,这里将真正扣除玩家账户中被锁定的金币,类似于信用卡的确定预授权完成刷卡
(3)扣除金币Cancel接口,取消扣除金币,被锁定的金币将返还到玩家的账户中,类似于信用卡的撤销预授权取消刷卡
第二,TCC编程模式下,SOA接口调用者如何使用这三个接口呢?
1、调用者先执行扣除金币Try接口,再去执行其他任务(比如添加道具);
2、当其他任务执行成功,调用者执行扣除金币Confirm接口确认扣除金币;
3、当其他任务执行异常,调用者则执行扣除金币Cancel接口取消扣除金币。

第三,图解TCC模式
这里我们假设添加道具的SOA接口也满足TCC模式,下图是使用TCC事务进行道具购买的时序图:
在这里插入图片描述
解释上图(TCC编程模式如何保证数据一致性)
在步骤[1]调用扣除金币Try接口时出现异常,调用扣除金币Cancel接口即可保证数据一致
在步骤[3]调用添加道具Try接口时出现异常,调用扣除金币Cancel接口与添加道具Cancel接口即可保证数据一致
在步骤[5]调用扣除金币Confirm接口时出现异常,调用扣除金币Cancel接口与添加道具Cancel接口即可保证数据一致
在步骤[7]调用添加道具Confirm接口时出现异常,由于扣除金币操作已经确定不能再取消,所以这里会引发数据不一致
小结:即使我们使用了TCC事务,也无法完美的保证各个SOA服务之间的数据一致性。但是,TCC事务为我们屏蔽了大多数异常导致的数据不一致,同时一般情况下,进行Confirm或Cancel操作时产生异常的概率极小极小,所以对于一些强一致性系统,我们还是会使用TCC事务来保证多个SOA服务之间的数据一致性。

4.5 最终一致性多数据库事务

问题提出:TCC事务的性能问题?
标准回答:使用最终一致性数据补偿机制,对于核心服务保证强一致性,对于非核心服务使用 消息队列+定时任务 保证最终一致性。
解释

有了TCC事务,我们能够保证多个SOA服务之间的数据一致性,但是,TCC事务存在不小的性能问题。
为了描述性能问题的产生,我们将交易系统的需求略作修改:游戏中的玩家使用金币购买道具A,系统将自动赠送给玩家道具B,道具C与道具D。
这里我们假设我们到道具服务不支持批量添加道具,而只有基于TCC模式的添加单个道具的接口。
为保证数据一致性,交易系统需要先调用扣除金币Try接口,然后再依次调用添加道具A、B、C、D的Try接口,最后再依次调用对应的Confirm接口。
如果这样做,因为TCC事务是先Try再Confirm的模式,接口调用量会翻倍,这在接口调用量小时性能影响并不明显,但上面的需求中我们执行扣除金币,添加道具A、B、C、D共有5个接口调用,翻倍后变为10个(解释:try五个接口,confirm五个接口),系统性能会大大降低。那么是否有既能保证数据一致性,又能保证性能的分布式事务方案?
回答:使用最终一致性数据补偿机制,对于核心服务保证强一致性,对于非核心服务使用 消息队列+定时任务 保证最终一致性。

解释最终一致性是如何使用数据补偿机制(消息队列+定时任务)实现的?
扣除金币,添加道具A、B、C、D,其中,前两个是核心,后三个是非核心,对于核心接口,要保证强一致性,两个先try,然后再confirm,对于非核心服务,没必要在时间上保证强一致性。

4.6 小结五种(最后全文小结,黄金金手指)

单数据库事务,包一层事务就好了,简单;
多数据库事务,
(1)还是像单数据库事务一样,执行一个提交一个,如果出现第二个mysql中的事务执行出错或提交出错,第一个mysql中的事务无法回滚。
(2)两个mysql先全部执行完成,然后提交,但是最后7 8 如果第二个mysql中事务提交失败,第一个mysql中事务无法回滚。
多数据库事务,两段式/三段式解决了这个问题,引入一个协调者
两段式和上面的先全部执行,全部为yes,再协调者发送命令,全部提交,但是还是存在最后7 8 如果第二个mysql中事务提交失败,第一个mysql中事务无法回滚。
三段式,全部ok之后,才能提交。
然后,从操作数据库变为操作SOA服务
第四,操作TCC编程模式,一个接口变三个接口,全部try,再全部commit,有一个失败的,全部回滚,依赖日志系统。
第五个,因为TCC try commit 使一个接口变成了两个接口性能下降,所以最终一致性,核心功能用TCC,非核心功能等核心功能执行完了之后再通过 消息队列+定时任务 通知,异步执行。

五、小结

分布式事务架构的五大演进:单数据库事务、基于后置提交的多数据库事务、基于两段式/三段式提交的多数据库事务、TCC多数据库事务、最终一致性多数据库事务。

天天打码,天天进步!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祖母绿宝石

打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值