05、分布式事务 实战 - 强一致性分布式解决方案

一、强一致性事务概述

在分布式事务领域,最早采用的是符合 CAP 理论的强一致性事务来解决分布式事务问题。强一致性分布式事务要求在任意时刻查询参与全局事务的各节点的数据都是一致的

1.典型方案

在强一致性事务解决方案中,典型的方案包括 DTP 模型(全局事务模型)、2PC 模型(二阶段提交模型)和 3PC(三阶段提交模型)3 种

基于DTP 模型,典型的解决方案是分布式通信协议 XA 规范,MySQL 默认支持 XA 规范。另外 Atomikis 框架和 Dromara 开源社区的 RainCat 框架也在应用层支持 XA 规范,能够实现分布式事务

基于2PC 模型,典型的解决方案是 Dromara 开源社区开源的 RainCat 框架,在应用层实现了 2PC 模型,避免出现在数据库层实现 2PC 模型时阻塞数据库的情况

由于3PC 模型的设计过于复杂,在解决 2PC 问题的同时又引入了新的问题,因此在实际工作中的应用不是很广泛

2.适用场景

在分布式事务解决方案中,强一致性事务要求应用程序在任何时间,读取任意节点上的数据,都是最新写入的

强一致性事务主要用于对数据一致性要求比较高,在任意时刻都要查询到最新写入数据的场景,例如跨行转账业务中,张三向李四转账 100 元,则张三账户减少 100 元,李四账户增加 100 元,这两个操作要么都执行成功,要么都执行失败。不存在一个成功,另一个失败的情况

3.优缺点

强一致性事务解决方案存在如下优点:

1、 数据一致性比较高;
2、 在任意时刻都能够查询到最新写入的数据;

强一致性事务解决方案也存在着如下缺点:

1、 存在性能问题,在分布式事务未完全提交和回滚之前,应用程序不会查询到最新的数据;
2、 实现复杂;
3、 牺牲了可用性;
4、 不适合高并发场景;

二、DTP 模型

DTP模型是 X/Open 组织定义的一套分布式事务标准,这套标准主要定义了实现分布式事务的规范和 API,具体的实现则交给相应的厂商来实现。本节对 DTP 模型的重要概念和执行流程进行简单的介绍

1.DTP 模型的重要概念

DTP模型种定义了几个重要的概念,分别为事务、全局事务、分支事务和控制线程

1、 事务:一个事务就是一个完整的工作单元,具备ACID特性;
2、 全局事务:由事务管理器管理的事务,能够一次性操作多个资源管理器;
3、 分支事务:由事务管理器管理的全局事务中,每个资源管理器中独立执行的事务;
4、 控制线程:执行全局事务的线程,这个线程用来关联应用程序、事务管理器和资源管理器三者之间的关系,也就是表示全局事务和分支事务的关系,通常称为事务上下文环境;

2.DTP 模型的执行流程

DTP模型定义了实现分布式事务的规范和 API,主要的执行流程如下图所示:

 

在DTP 模型中,主要定义了 3 个核心组件,分别为 AP、TM、RM:

  • AP:应用程序(Application Program)可以理解为参与 DTP 分布式事务模型的应用程序
  • RM:资源管理器(Resource Manager)可以理解为数据库管理系统或者消息服务管理器。应用程序可以通过资源管理器和对相应的资源进行有效的控制。相应的资源需要实现 XA 定义的接口
  • TM:事务管理器(Transaction Manager)负责协调和管理 DTP 模型中的事务,为应用程序提供编程接口,同时管理资源管理器

其中,AP 可以和 TM、RM 通信,TM 和 RM 互相之间可以通信,DTP 模型定义了 XA 接口,TM 和 RM 能够通过 XA 接口进行双向通信。TM 控制着全局事务,管理事务的生命周期并协调资源。RM 控制和管理实际的资源

三、2PC 模型

2PC模型是指两阶段提交协议模型,这种模型将整个事务流程分为 Prepare 阶段和 Commit 阶段。2PC 中的 2 指的是两个阶段,P 是指 Prepare,即准备,C 是指 Commit,即提交

1.2PC 模型的执行流程

Prepare 阶段

在Prepare 阶段,事务管理器给每个参与全局事务的资源管理器发送 Prepare 消息,资源管理器要么返回失败,要么在本地执行相应的事务,将事务写入本地的 Redo Log 文件和 Undo Log 文件,此时,事务并没有提交

Commit 阶段

如果事务管理器收到了参与全局事务的资源管理器返回的失败消息,则直接给 Prepare 阶段执行成功的资源管理器发送回滚消息,否则,向每个资源管理器发送 Commit 消息。相应的资源管理器根据事务管理器发送过来的消息指令,执行对应的事务回滚或事务提交操作,并且释放事务处理过程中使用的锁资源

2PC的流程分为事务提交成功和事务提交失败两种情况,下面进行详细介绍

2.事务执行成功的流程

在2PC 模型中,正常情况下,分布式事务执行成功时,整体上也分为 Prepare 阶段和 Commit 阶段。在 Prepare 阶段事务管理器会向各资源管理器发送 Prepare 消息,在 Commit 阶段事务管理器会向个资源管理器发送 Commit 消息

事务执行成功的流程如下图所示:

 

由上图可以看出,事务提交成功的情况下,在 2PC 的 Prepare 阶段,由事务管理器向参与全局事务的资源管理器发送 Prepare 消息,资源管理器受到消息后,将事务写入本地的 Redo Log 和 Undo Log 日志,并向事务管理器返回事务执行成功的状态

由下图可以看出,事务执行成功的情况下,在 2PC 的 Commit 阶段,由事务管理器向参与全局事务的资源管理器发送 Commit 消息,资源管理器收到消息后,提交本地事务,并将提交成功的消息返回给事务管理器,同时释放相应的锁资源

 

3.事务执行失败的流程

在2PC 模型中,当执行分布式事务失败时,例如在 Prepare 阶段,某些资源管理器向事务管理器响应了 Error 消息,则在 Commit 阶段,事务管理器会向其他响应正常消息的资源管理器发送回滚消息

 

由上图可以看出,事务执行失败的情况下,在 2PC 的 Prepare 阶段,事务管理器向资源管理器发送 Prepare 消息,某些资源管理器收到消息后,将事务写入本地 Redo Log 和 Undo Log 日志失败,会向事务管理器返回执行失败的消息

 

由上图可以看出,事务执行失败的情况下,在 2PC 的 Commit 阶段,事务管理器会向在 Prepare 阶段执行事务成功的资源管理器发送 Rollback 消息,对应的资源管理器收到事务管理器发送的 Rollback 消息后,回滚本地的事务,并将回滚成功的消息返回给事务管理器

4.2PC 模型存在的问题

值得注意的是,2PC 模型存在着如下的缺点:

1、 同步阻塞问题:事务的执行过程中,所有参与事务的节点都会对其占用的公共资源加锁,导致其他访问公共资源的进程或者线程阻塞;
2、 单点故障问题:如果事务管理器发生故障,则资源管理器会一直阻塞;
3、 数据不一致问题:如果在Commit阶段,由于网络或者部分资源管理器发生故障,导致部分资源管理器没有接收到事务管理器发送过来的Commit消息,会引起数据不一致的问题;
4、 无法解决的问题:如果在Commit阶段,事务管理器发出Commit消息后宕机,并且唯一接收到这条Commit消息的资源管理器也宕机了,则无法确认事务是否已经提交;

四、3PC 模型

3PC模型是指三阶段提交模型,是在 2PC 模型的基础上改进的版本。3PC 模型把 2PC 模型中的 Prepare 阶段一分为二,最终形成 3 个阶段:CanCommit 阶段、PreCommit 阶段和 doCommit 或者 doRollback 阶段

1.事务执行成功的流程

在3PC 模型中,当事务执行成功时,在 CanCommit 阶段、PreCommit 阶段和 doCommit 阶段,事务管理器与资源管理器之间的消息发送与接收都是正常的,整个分布式事务最终会成功提交

 

由上图可以看出,在事务执行成功的 CanCommit 阶段,事务管理器向参与全局事务的资源管理器发送 CanCommit 消息,资源管理器收到 CanCommit 消息,认为能够执行事务,会向事务管理器响应 Yes 消息,进入预备状态

 

由上图可以看出,在事务执行成功的 PreCommit 阶段,事务管理器会向参与全局事务的资源管理器发送 PreCommit 消息,资源管理器收到 PreCommit 消息后,执行事务操作,将 Undo 和 Redo 信息写入事务日志,并向事务管理器响应 Ack 状态,但此时不会提交事务

 

由上图可以看出,在事务执行成功的 doCommit 阶段,事务管理器会向参与全局事务的资源管理器发送 doCommit 消息,事务管理器接收到 doCommit 消息后,正式提交事务,并释放执行事务期间占用的资源,同时向事务管理器响应事务已提交的状态。事务管理器收到资源管理器相应的事务已提交的状态,完成事务的提交

2.事务执行失败的流程

在3PC 模型中,某些资源管理器接收到事务管理器发送过来的 CanCommit 消息时,如果资源管理器认为不能执行事务,则会向事务管理器响应无法执行事务的 No 消息。之后事务管理器会在 PreCommit 阶段向资源管理器发送准备回滚的消息,资源管理器向事务管理器响应准备好事务回滚的消息。在 doRollback 阶段,事务管理器会向资源管理器发送回滚事务的消息

 

由上图可以看出,在事务执行失败的 CanCommit 阶段,事务管理器会向参与全局事务的资源管理器发送 CanCommit 消息,如果资源管理器收到 CanCommit 消息后,认为不能执行事务,则会向事务管理器响应 No 状态

 

由上图可以看出,在事务执行失败的 PreCommit 阶段,事务管理器会向参与全局事务的资源管理器发送 Abort 消息,资源管理器收到 Abort 消息或者期间出现超时,都会中断事务的执行

 

由上图可以看出,在事务执行失败的 doRollback 阶段,事务管理器会向参与全局事务的资源管理器发送 Rollback 消息,资源管理器会利用 Undo Log 日志信息回滚事务,并释放执行事务期间占用的资源,向事务管理器返回事务已回滚的状态。事务管理器收到资源管理器返回的事务已回滚的消息,完成事务回滚

3.3PC 模型种存在的问题

与2PC 模型相比,3PC 模型主要解决了单点故障问题,并减少了事务执行过程中产生的阻塞现象。在 3PC 模型中,如果资源管理器无法及时收到来自事务管理器发出的消息,那么资源管理器就会执行提交事务的操作,而不是一直持有事务的资源并处于阻塞状态,但是这种机制会导致数据不一致的问题

如果由于网络故障等原因,导致资源管理器没有及时收到事务管理器发出的 Abort 消息,则资源管理器会在一段时间后提交事务,这就导致与其他接收到 Abort 消息并执行了事务回滚操作的资源管理器的数据不一致