分布式事务(二)、刚性事务之 2PC、3PC

目录

前言

XA

2PC

3PC


分布式事务:

分布式事务(一)、CAP,BASE理论


前言

在前面的文章中我们提到了刚性事务遵循ACID原则,满足强一致性,本篇讲解刚性事务的标准实现2PC(二阶段提交)和3PC(三阶段提交)。

XA

XA协议是X/Open CAE Specification定义的一套DTP(Distributed Transaction Processing)分布式事务处理模型,主要包含四个部分:

  • 应用程序(AP):应用程序
  • 事务管理器(TM):交易中间件
  • 资源管理器(RM):数据库
  • 通信资源管理器(CRM):消息中间件

事务管理器作为一个全局的调度者,负责通知各个资源管理器事务的开始、结束、提交、回滚,把多个本地事务协调为全局统一的分布式事务。两阶段提交(2PC)和三阶段提交(3PC)就是基于此协议衍生出来的。Oracle、Mysql等数据库均已实现了XA接口。

2PC

2PC 是二阶段提交(Two-phase Commit)的缩写,分为两个阶段完成,第一个阶段是准备阶段(prepare),第二个阶段是提交阶段(commit/rollback),准备阶段和提交阶段都是由事务管理器(协调者)发起的,协调的对象是资源管理器(参与者)。 

  1. 准备阶段:协调者向所有参与者发起指令,每个参与者评估自己的状态,如果参与者评估指令可以完成,参与者会写 redo 和 undo 日志,然后锁定资源,执行操作,但不提交。
  2. 提交阶段:如果所有参与者返回准备成功,即预留资源和执行操作成功,协调者会向所有参与者发起提交指令,参与者提交资源变更的事务,释放锁定的资源;如果任何一个参与者返回准备失败,即预留资源或者执行操作失败,协调者会向所有参与者发起中止指令,参与者取消已经变更的事务,执行 undo 日志并释放锁定的资源。 

分布式事务(二)、刚性事务之 2PC、3PC

二阶段提交(2PC)的缺点:

  • 阻塞:事务执行过程中所有参与者都是阻塞型的,占用的资源被一直锁定,不会被释放,第三方参与者访问参与者占有的资源时会被阻塞,影响性能;
  • 单点故障:协调者一旦发生故障,参与者与协调者失去同步,参与者会被一直阻塞。尤其在提交阶段,所有参与者都处于锁定资源状态中,无法完成事务操作;(虽然可以选举出新的协调者,但仍然无法解决参与者被阻塞的问题);
  • 数据不一致:提交阶段协调者向参与者发送提交指令,发生局部网络故障,会出现一部分参与者未收到提交指令无法提交事务的情况,导致多个参与者之间出现数据不一致的现象;

二阶段提交协议在准备阶段需要等待所有参与者的反馈,因此可能造成数据库资源锁定时间过长,不适合高并发和子事务生命周长较长的业务场景。两阶段提交牺牲了一部分可用性来换取一致性。 

3PC

3PC是三阶段提交(Three-phase Commit)的缩写,是对2PC 的改进,3PC在2PC的准备阶段提交阶段中加入一个预提交阶段。保证了在最后提交阶段之前,各参与者节点的状态都一致。同时在协调者和参与者中都引入超时机制解决了阻塞的问题,当参与者由于各种原因未收到协调者的commit 请求后,会对本地事务进行commit,不会一直阻塞等待,解决了2PC的单点故障问题,因此维基百科中定义3PC为“非阻塞”协议。

3PC 的三个阶段:CanCommit(准备阶段)、PreCommit(预提交阶段)、DoCommit(提交阶段)

  1. 准备阶段:协调者询问参与者是否可以执行事务提交操作,协调者只需要回答是还是不是,而不需要做真正的操作,这个阶段参与者在等待超时后会自动中止。
  2. 预提交阶段:如果在CanCommit准备阶段所有的参与者都返回可以执行操作,协调者向所有参与者发送预提交请求,然后参与者写 redo 和 undo 日志,锁定资源,执行操作,但不提交;如果在CanCommit准备阶段任何一个参与者返回不能执行操作的结果,则协调者向所有参与者发送中止指令。这里与两阶段提交协议的准备阶段是相似的,此阶段的参与者在等待超时后会自动提交。
  3. 提交阶段:如果所有参与者在PreCommit预提交阶段都返回成功,也就是预留资源和执行操作成功,协调者向参与者发起提交指令,参与者提交资源变更的事务,释放锁定的资源;如果任何一个参与者返回失败,也就是预留资源或者执行操作失败,协调者向所有参与者发起中止指令,参与者取消已经变更的事务,执行 undo 日志,释放锁定的资源。这里与两阶段提交协议的提交阶段一致。

超时机制

  • 如果在CanCommit 准备阶段等待超时,则自动中止;
  • 如果在PreCommit预提交阶段等待超时,则自动提交。

分布式事务(二)、刚性事务之 2PC、3PC

3PC 通过预提交阶段可以减少故障恢复时候的复杂性,但3PC 还是没能从根本上解决数据一致性的问题,比如在预提交阶段时协调者和其中一个参与者都发生了故障,此时其他参与者在超时情况下会自动选择提交或回滚,当新选举出的协调者上任时也会给活着的参与者发送提交命令,但发生故障的那个参与者还未恢复且无法确定是否执行了事务,这里就出现了数据不一致的情况。

事实上 2PC 和 3PC 都无法保证完全的数据一致性,于是需要利用补偿机制尽量确保数据的一致性,在后面的文章中会具体介绍。

 

希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!