分布式事务:深入理解什么是2pc,3pc及tcc协议

jingjiren jingjiren     2022-12-08     476

关键词:

 1. 导读

  对于分布式事务的概念,可能还会有很多同学不理解或者理解得不是很深刻的地方,在这篇文章中,作者打算重点给大家先介绍下分布式事务相关的基本概念,诸如2PC、3PC、TCC之类的基本问题。

2.  数据库事务的概念

  在讲述分布式事务的概念之前,我们先来回顾下事务相关的一些概念。

事务的基本概念:

  就是一个程序执行单元,里面的操作要么全部执行成功,要么全部执行失败,不允许只成功一半另外一半执行失败的事情发生。例如一段事务代码做了两次数据库更新操作,那么这两次数据库操作要么全部执行成功,要么全部回滚。

事务的基本特性

我们知道事务有4个非常重要的特性,即我们常说的(ACID)。

  Atomicity(原子性):是说事务是一个不可分割的整体,所有操作要么全做,要么全不做;只要事务中有一个操作出错,回滚到事务开始前的状态的话,那么之前已经执行的所有操作都是无效的,都应该回滚到开始前的状态。

  Consistency(一致性):是说事务执行前后,数据从一个状态到另一个状态必须是一致的,比如A向B转账(A、B的总金额就是一个一致性状态),不可能出现A扣了钱,B却没收到的情况发生。

  Isolation(隔离性):多个并发事务之间相互隔离,不能互相干扰。关于事务的隔离性,可能不是特别好理解,这里的并发事务是指两个事务操作了同一份数据的情况;而对于并发事务操作同一份数据的隔离性问题,则是要求不能出现脏读、幻读的情况,即事务A不能读取事务B还没有提交的数据,或者在事务A读取数据进行更新操作时,不允许事务B率先更新掉这条数据。而为了解决这个问题,常用的手段就是加锁了,对于数据库来说就是通过数据库的相关锁机制来保证。

  Durablity(持久性):事务完成后,对数据库的更改是永久保存的,不能回滚。

  关于数据库事务的基本概念大家可以去网上搜一下,这里只是给大家回顾下事务的基本概念及特性,诸如事务并发问题、事务隔离级别等大家如有遗忘可以去回顾下(tips:面试经常会问到的问题哦)。

3. 什么是分布式事务

  以上内容我们回顾了下事务的基本概念,那么分布式事务又是个什么概念呢?它与数据库事务之间又有什么区别呢?

  其实分布式事务从实质上看与数据库事务的概念是一致的,既然是事务也就需要满足事务的基本特性(ACID),只是分布式事务相对于本地事务而言其表现形式有很大的不同。举个例子,在一个JVM进程中如果需要同时操作数据库的多条记录,而这些操作需要在一个事务中,那么我们可以通过数据库提供的事务机制(一般是数据库锁)来实现。

  而随着这个JVM进程(应用)被拆分成了微服务架构,原本一个本地逻辑执行单元被拆分到了多个独立的微服务中,这些微服务又分别操作不同的数据库和表,服务之间通过网络调用。

  举个例子:服务A收到一笔购物下单请求后,需要调用服务B去支付,支付成功则处理购物订单为待发货状态,否则就需要将购物订单处理为失败状态。(如图所示)

技术图片

  在上面这个例子中会不会出现服务B支付成功了,但是由于网络调用的问题没有通知到服务A,导致用户付了钱,但是购物订单无法显示支付成功的状态呢?

  答案是这种情况是普遍存在的,因为服务B在处理成功后需要向服务A发送网络请求,而这个过程是极有可能失败的。那么如何确保“服务A->服务B”这个过程能够组成一个事务,要么全部成功、要么全部失败呢?而这就是典型的需要通过分布式事务解决的问题。

  分布式事务是为了解决微服务架构(形式都是分布式系统)中不同节点之间的数据一致性问题。这个一致性问题本质上解决的也是传统事务需要解决的问题,即一个请求在多个微服务调用链中,所有服务的数据处理要么全部成功,要么全部回滚。当然分布式事务问题的形式可能与传统事务会有比较大的差异,但是问题本质是一致的,都是要求解决数据的一致性问题。

  而分布式事务的实现方式有很多种,最具有代表性的是由Oracle Tuxedo系统提出的XA分布式事务协议。XA协议包括两阶段提交(2PC)三阶段提交(3PC)两种实现,接下来我们分别来介绍下这两种实现方式的原理。

4. 两阶段提交(2PC)

  两阶段提交又称2PC(two-phase commit protocol),2pc是一个非常经典的强一致、中心化的原子提交协议。这里所说的中心化是指协议中有两类节点:一个是中心化协调者节点(coordinator)N个参与者节点(partcipant)

  下面我们就以一个尽量贴近实际业务场景的操作来举例:"假设在一个分布式架构的系统中事务的发起者通过分布式事务协调者(如RocketMQ,在早期RocketMQ版本不提供事务消息特性时,有些公司会自己研发一个基于MQ的可靠消息服务来实现一定的分布式事务的特性)分别向应用服务A、应用服务B发起处理请求,二者在处理的过程中会分别操作自身服务的数据库,现在要求应用服务A、应用服务B的数据处理操作要在一个事务里"?

  在上面这个例子中如果采用两阶段提交来实现分布式事务,那么其运行原理应该是个什么样的呢?(如??):

第一阶段:请求/表决阶段(点击放大)

技术图片

  既然称为两阶段提交,说明在这个过程中是大致存在两个阶段的处理流程。第一个阶段如??图所示,这个阶段被称之为请求/表决阶段。是个什么意思呢?

  就是在分布式事务的发起方在向分布式事务协调者(Coordinator)发送请求时,Coordinator首先会分别向参与者(Partcipant)节点A、参与这节点(Partcipant)节点B分别发送事务预处理请求,称之为Prepare,有些资料也叫"Vote Request"。

  说的直白点就是问一下这些参与节点"这件事你们能不能处理成功了",此时这些参与者节点一般来说就会打开本地数据库事务,然后开始执行数据库本地事务,但在执行完成后并不会立马提交数据库本地事务,而是先向Coordinator报告说:“我这边可以处理了/我这边不能处理”。

  如果所有的参与这节点都向协调者作了“Vote Commit”的反馈的话,那么此时流程就会进入第二个阶段了。

第二阶段:提交/执行阶段(正常流程)

技术图片

  如果所有参与者节点都向协调者报告说“我这边可以处理”,那么此时协调者就会向所有参与者节点发送“全局提交确认通知(global_commit)”,即你们都可以进行本地事务提交了,此时参与者节点就会完成自身本地数据库事务的提交,并最终将提交结果回复“ack”消息给Coordinator,然后Coordinator就会向调用方返回分布式事务处理完成的结果。

第二阶段:提交/执行阶段(异常流程)

技术图片

  相反,在第二阶段除了所有的参与者节点都反馈“我这边可以处理了”的情况外,也会有节点反馈说“我这边不能处理”的情况发生,此时参与者节点就会向协调者节点反馈“Vote_Abort”的消息。此时分布式事务协调者节点就会向所有的参与者节点发起事务回滚的消息(“global_rollback”),此时各个参与者节点就会回滚本地事务,释放资源,并且向协调者节点发送“ack”确认消息,协调者节点就会向调用方返回分布式事务处理失败的结果。

  以上就是两阶段提交的基本过程了,那么按照这个两阶段提交协议,分布式系统的数据一致性问题就能得到满足吗

  实际上分布式事务是一件非常复杂的事情,两阶段提交只是通过增加了事务协调者(Coordinator)的角色来通过2个阶段的处理流程来解决分布式系统中一个事务需要跨多个服务节点的数据一致性问题。但是从异常情况上考虑,这个流程也并不是那么的无懈可击

  假设如果在第二个阶段中Coordinator在接收到Partcipant"Vote_Request"后挂掉了或者网络出现了异常,那么此时Partcipant节点就会一直处于本地事务挂起的状态,从而长时间地占用资源。当然这种情况只会出现在极端情况下,然而作为一套健壮的软件系统而言,异常Case的处理才是真正考验方案正确性的地方。

以下几点是XA-两阶段提交协议中会遇到的一些问题:

  • 性能问题。从流程上我们可以看得出,其最大缺点就在于它的执行过程中间,节点都处于阻塞状态。各个操作数据库的节点此时都占用着数据库资源,只有当所有节点准备完毕,事务协调者才会通知进行全局提交,参与者进行本地事务提交后才会释放资源。这样的过程会比较漫长,对性能影响比较大。

  • 协调者单点故障问题。事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,会导致参与者收不到提交或回滚的通知,从而导致参与者节点始终处于事务无法完成的中间状态。

  • 丢失消息导致的数据不一致问题。在第二个阶段,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就会导致节点间数据的不一致问题。

既然两阶段提交有以上问题,那么有没有其他的方案来解决呢?

5. 三阶段提交(3PC)

  三阶段提交又称3PC,其在两阶段提交的基础上增加了CanCommit阶段,并引入了超时机制。一旦事务参与者迟迟没有收到协调者的Commit请求,就会自动进行本地commit,这样相对有效地解决了协调者单点故障的问题。

  但是性能问题和不一致问题仍然没有根本解决。下面我们还是一起看下三阶段流程的是什么样的?

第一阶段:CanCommit阶段

技术图片

  这个阶段类似于2PC中的第二个阶段中的Ready阶段,是一种事务询问操作,事务的协调者向所有参与者询问“你们是否可以完成本次事务?”,如果参与者节点认为自身可以完成事务就返回“YES”,否则“NO”。而在实际的场景中参与者节点会对自身逻辑进行事务尝试,其实说白了就是检查下自身状态的健康性,看有没有能力进行事务操作。

第二阶段:PreCommit阶段

技术图片

  在阶段一中,如果所有的参与者都返回Yes的话,那么就会进入PreCommit阶段进行事务预提交。此时分布式事务协调者会向所有的参与者节点发送PreCommit请求,参与者收到后开始执行事务操作,并将Undo和Redo信息记录到事务日志中。参与者执行完事务操作后(此时属于未提交事务的状态),就会向协调者反馈“Ack”表示我已经准备好提交了,并等待协调者的下一步指令。

  否则,如果阶段一中有任何一个参与者节点返回的结果是No响应,或者协调者在等待参与者节点反馈的过程中超时(2PC中只有协调者可以超时,参与者没有超时机制)。整个分布式事务就会中断,协调者就会向所有的参与者发送“abort”请求。

第三阶段:DoCommit阶段

技术图片

  在阶段二中如果所有的参与者节点都可以进行PreCommit提交,那么协调者就会从“预提交状态”-》“提交状态”。然后向所有的参与者节点发送"doCommit"请求,参与者节点在收到提交请求后就会各自执行事务提交操作,并向协调者节点反馈“Ack”消息,协调者收到所有参与者的Ack消息后完成事务。

  相反,如果有一个参与者节点未完成PreCommit的反馈或者反馈超时,那么协调者都会向所有的参与者节点发送abort请求,从而中断事务。

  看到这里,你是不是会疑惑"3PC相对于2PC而言到底优化了什么地方呢?"

  相比较2PC而言,3PC对于协调者(Coordinator)和参与者(Partcipant)都设置了超时时间,而2PC只有协调者才拥有超时机制。这解决了一个什么问题呢?这个优化点,主要是避免了参与者在长时间无法与协调者节点通讯(协调者挂掉了)的情况下,无法释放资源的问题,因为参与者自身拥有超时机制会在超时后,自动进行本地commit从而进行释放资源。而这种机制也侧面降低了整个事务的阻塞时间和范围。

  另外,通过CanCommit、PreCommit、DoCommit三个阶段的设计,相较于2PC而言,多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的。

  以上就是3PC相对于2PC的一个提高(相对缓解了2PC中的前两个问题),但是3PC依然没有完全解决数据不一致的问题。

6. 补偿事务(TCC)

  说起分布式事务的概念,不少人都会搞混淆,似乎好像分布式事务就是TCC。实际上TCC与2PC、3PC一样,只是分布式事务的一种实现方案而已。

TCC(Try-Confirm-Cancel)又称补偿事务。其核心思想是:"针对每个操作都要注册一个与其对应的确认和补偿(撤销操作)"。它分为三个操作:

  • Try阶段:主要是对业务系统做检测及资源预留。

  • Confirm阶段:确认执行业务操作。

  • Cancel阶段:取消执行业务操作。

  TCC事务的处理流程与2PC两阶段提交类似,不过2PC通常都是在跨库的DB层面,而TCC本质上就是一个应用层面的2PC,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能

  而不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现try、confirm、cancel三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口还必须实现幂等。

TCC的具体原理图如??:

技术图片

7. 消息队列MQ事务

  在前面介绍2PC、3PC的时候我们说没有根本解决性能问题,而如果通过MQ的事务消息来进行异步解耦,并实现系统的数据的最终一致性的话会不会好很多呢?实际上这就是我们下一篇文章要继续讲述的《分布式事务之如何基于RocketMQ的事务消息特性实现分布式系统的最终一致性?》。敬请期待!

来源于无敌码农 ,作者无敌码农

深入理解分布式系统的2pc和3pc

深入理解分布式系统的2PC和3PC关注我的博客(http://www.hollischuang.com)的人可能都知道,我之前写过一篇文章专门介绍了一下2PC和3PC(详见:关于分布式事务、两阶段提交协议、三阶提交协议)。上一篇文章中主要介绍了下这两种... 查看详情

.netcorewith微服务-分布式事务-tcc

上一次我们讲解了分布式事务的2PC、3PC。那么这次我们来理一下TCC事务。本次还是讲解TCC的原理跟.NET其实没有关系。TCCTry准备阶段,尝试执行业务Confirm完成业务Cancel回滚准备阶段的业务TCC事务其实是2PC的一个扩展。上一次... 查看详情

详解分布式事务解决方案之tcc机制

前言之前讲解了分布式事务的解决方案之2PC和3PC,今天主要讲解事务补偿机制(TCC),Let'sgo!TCCTCC事务补偿是基于2PC实现的业务层事务控制方案,它是try,Confirm,Cancel三个单词的首字母,含义如下:try... 查看详情

分布式架构,刚性事务-2pc必须注意的问题及3pc详细解

2PC必须注意的问题咱们上文介绍了分布式事务的常见方案、类型划分、2PC的起源和流程。但是不幸的是2PC还是存在几个问题:1、全流程的同步阻塞:不管是第一阶段还是第二阶段,所有参与节点都是事务阻塞型。当参与者占有... 查看详情

分布式事务方案-补充

  在之前分布式一致性问题博客中提到了关于分布式事务一致性问题的两种解决方案,2PC和3PC,2PC用在数据库层面解决数据库之间的分布式事务;因此实际应用中往往不会采用这两个方案,下面说一下其他的解决方案TCC:  ... 查看详情

事务相关知识点|分布式事务|cap理论|2pc|3pc|

...a;2.什么是Spring事务:3.什么是本地事务:4.什么是分布式事务:5.什么是CAP理论: 5.1.一致性Consistency: 5.2.可用性Availability: 5.3.分区容错性Partitiontolerance: 5.4.分布式系统能否兼顾C、A、P& 查看详情

事务相关知识点|分布式事务|cap理论|2pc|3pc|

...a;2.什么是Spring事务:3.什么是本地事务:4.什么是分布式事务:5.什么是CAP理论: 5.1.一致性Consistency: 5.2.可用性Availability: 5.3.分区容错性Partitiontolerance: 5.4.分布式系统能否兼顾C、A、P& 查看详情

分布式事务详解

🏆今日学习目标:🍀分布式事务详解✅创作者:林在闪闪发光⏰预计时间:30分钟🎉个人主页:林在闪闪发光的个人主页 🍁林在闪闪发光的个人社区,欢迎你的加入: 林在闪闪发光的社区目... 查看详情

分布式(一致性可用性可用性)-cap理论概述-分布式事务(2pc-3pc-tcc)(代码片段)

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance)这三项中的两项数据一致性(consistency):如果系统对一个写操作返回成功,那么之后的读... 查看详情

分布式一致性协议之2pc与3pc

...2PC与3PC的流程图,以及对比它们之间的关系和区别。 分布式事务是为了解决微服务架构(形式都是分布式系统)中不同节点之间的数据一致性问题。这个一致性问题本质上解决的也是传统事务需要解决的问题,即一个请求在... 查看详情

seata分布式事务解决方案汇总

文章目录概述什么是分布式事务分布式事务为什么难CAP理论base理论一致性模型分布式事务解决方案2PC:两阶段提交2PC存在的问题3PC:三阶段提交cancommitprecommitcommit3PC相对于2PC的优缺点XATCCMQ事务消息(可靠消息)本地事务消息表(可... 查看详情

一致性协议之2pc,3pc

2PC 简述:2PC是用来解决分布式事务的原子性问题,通过将事务的操作分成两步来完成。在执行的过程中,有两种角色,分别是协调者和参与者,协调者负责整体的调度和协调,参与者负责具体事务的执行执行过程阶段一:提... 查看详情

还不理解“分布式事务”?这篇给你讲清楚!

这篇文章将介绍什么是分布式事务,分布式事务解决什么问题,对分布式事务实现的难点,解决思路,不同场景下方案的选择,通过图解的方式进行梳理、总结和比较。相信耐心看完这篇文章,谈到分布式事务,不再只是有&ldquo... 查看详情

让您轻松理解分布式事务解决方案之tcc(代码片段)

1.什么是TCCTCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作既回... 查看详情

distributed--2pc和3pc

在分布式系统中,每一个机器节点虽然都能够明确地知道自己在进行事务操作过程中的结果是成功或失败,但却无法直接获取到其他分布式节点的操作结果.因此,当一个事务操作需要跨越多个分布式节点的时候,为了保持事务处理的A... 查看详情

阿里4面:聊聊分布式事务的解决方案???(代码片段)

阿里4面:聊聊分布式事务的解决方案???公众号关注“架构师学习营”设为“星标”,带你学习更多架构师知识!大家好,这里是架构师学习营。本文继续分享分布式事务的另一种常见的解决方案:TCC什么是TCC?TCC场景案例TCC... 查看详情

1pc,2pc,3pc

...it,要么rollback 2PC,twophasecommit,二阶段提交用于解决分布式事务,涉及到多个数据源的事务需要有TM(TransactionManagers,事务管理器,直接与应用通信)与RM(ResourceManager,资源 查看详情

分布式系统理论

...理、BASE理论、2PC、3PC1.2.1CAP理论1.2.2BASE理论1.2.32PC(分布式事务)1.2.43PC(分布式事务)1.3TCC(Try-Confirm-Cancel)理论2设计2.1限流策略1基础 1.1一致性hash算法深入一致性哈希(Consi 查看详情