聊聊分布式事务 (2)

BASE 是对CAP 中 AP 方案的一种补充。在 BASE 中用软状态和最终一致,保证了延迟后的一致性。BASE 和 ACID 是相反的,ACID 是一种强一致性模型,而 BASE 却是牺牲这种强一致性,允许数据短时间内不一致,最终一致性。

接下来我们看看分布式事务有哪几种实现方案。

分布式事务实现方案

基于数据库资源层面

2PC 两阶段提交协议

3PC 三阶段提交协议

基于业务层面

TCC

基于数据库资源层面实现方案,由于存在多个事务,我们需要存在一个角色管理各个事务的状态。我们将这个角色称为协调者,事务参与者称为参与者。参与者与协调者一般会基于某种特定协议,目前比较有名的为 XA 接口协议。基于协调者与参与者的思想设定,分别提出了 2PC 与 3PC 实现XA 分布式事务。

2PC 两阶段提交协议

如名字所知,这个过程主要分为两步。

第一阶段,协调者(事务管理器)将涉及到事务的进行预提交,这个时候数据库资源开始被锁定。参与者将 undo 与 redo 写入事务日志。
第二阶段,参与者(资源管理器)行提交事务,或者利用 undo 日志回滚事务,释放资源。

整个过程如下图。

分布式事务提交成功场景:

成功

分布式事务回滚场景:

回滚

该方案的优点为:实现比较简单,主流数据库都支持,强一致性。MySQL 5.5 以后基于 XA 协议实现.

相应该方案也存在缺点:

协调者的单点问题。若协调者在提交阶段宕机,参与者一直在等待,就一直锁定资源,一直阻塞。虽然可以重新选举协调者,但是无法解决该问题。

同步阻塞时间过长,整个执行过程事务是阻塞的,直到提交完成,释放资源,若在提交过程/回滚过程,因为网络延时,参与者一直未收到指令,则参与者一直被阻塞。

数据不一致。第二阶段,协调者发出第一个提交信号后后宕机,则第一个参与者提交事务,第二个参与者因为未收到协调者信号,无法进行事务提交。

于是针对 2PC 存在的缺点,提出改进方案,3PC。

3PC 三阶段提交协议

三阶段提交,在两阶段提交的基础下,改进两阶段。三阶段步骤如下。

CanCommit,协调者询问参与者是否可以进行事务提交。

PreCommit ,若所有参与者可以进行事务提交,协调者下达 PreCommit 命令,参与者锁定资源,并等待最终命令。

所有参与者返回确认信息,协调者向各个事务下发事务执行通知,锁定资源,并将执行情况返回。

部分参与者返回否认信息或协调者等待超时。这种情况,协调者认为事务无法正常执行,下发中断指令,各个参与者退出预备状态

Do Commit,若第二阶段全部回应 ack,则下达 Do Commit ,进行事务最终提交,否则下达中断事务命令,所有参与者进行事务回滚。

所有参与者正常执行执行事务,协调者下发最终提交指令,释放锁定资源。

部分参与者执行事务失败,协调者等待超时,协调者下发回滚指令,释放锁定资源。

具体见下图。

三阶段提交图

三阶段提交对比两阶段,引入超时机制减少事务阻塞,解决单点故障。在第三阶段,一旦参与者无法接受到协调者信号时,等待超时之后,参与者默认执行 commit,释放资源。

三阶段任然不能解决数据一致性问题。若协调者发出回滚命令,但是由于网络问题,参与者在等待时间内都无法接收到,这时参与者默认提交事务,而其他事务进行了回滚,造成事务不一致。

TCC

TCC 事务

为了解决在事务运行过程中大颗粒度资源锁定的问题,业界提出一种新的事务模型,它是基于业务层面的事务定义。锁粒度完全由业务自己控制。它本质是一种补偿的思路。它把事务运行过程分成 Try、Confirm / Cancel 两个阶段。在每个阶段的逻辑由业务代码控制。这样就事务的锁粒度可以完全自由控制。业务可以在牺牲隔离性的情况下,获取更高的性能。

TCC 分别为 Trying,Confirm,Cancel 三个单词缩写。不同于 2PC 与 3PC 基于数据库层面,TCC 基于应用层面。
TCC 三个动作分别为:

Trying:

完成所有业务检查(一致性)

预留必须业务资源(准隔离性)

Confirm:

真正执行业务

Confirm操作要满足幂等性

Cancel:

释放Try阶段预留的业务资源

Cancel操作要满足幂等性

上面说法,一听起来有点生涩难懂,没关系我们使用实际案例解释。

下面我们模拟商城一次支付过程。用户下单使用组合支付,即余额加红包支付。一次正常流程为:

创建订单

下单

调用余额系统,扣减余额

调用红包系统,扣减红包余额

修改订单状态为已支付

完后支付。

实际过程如下图。

下单过程

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzwzz.html