分布式事务三阶段协议
分布式事务的三阶段分别是准备阶段、预提交阶段和提交 / 回滚阶段,以下是详细介绍:
三阶段提交协议可以理解为两阶段提交协议的改良版,是在协调者和参与者中都引入超时机制,并且把两阶段提交协议的第一个阶段分成了两步: 询问,然后再锁资源,最后真正提交。
两阶段提交协议最早是分布式事务的专家Jim Gray在1978年的一篇文章Notes on Database Operating Systems中提及。两阶段提交协议可以保证数据的强一致性,即保证了分布式事务的原子性:所有结点要么全做要么全不做。许多分布式关系型数据管理系统采用此协议来完成分布式事务。它是协调所有分布式原子事务参与者,并决定提交或取消(回滚)的分布式算法。同时也是解决一致性问题的算法。该算法能够解决很多的临时性系统故障(包括进程、网络节点、通信等故障),被广泛地使用。但是,它并不能够通过配置来解决所有的故障,在某些情况下它还需要人为的参与才能解决问题。两阶段提交协议存在的问题是,协调者在某些时刻如果失败了, 整个事务就会阻塞。于是Skeen发布了"NonBlocking Commit Protocols" (1981)这篇论文,论文指出在一个分布式的事务里面, 需要一个三阶段的提交协议来避免在两阶段提交中存在的阻塞问题。
准备阶段(CanCommit)
- 事务询问:协调者向所有参与者发送包含事务内容的
CanCommit
请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应。 - 各参与者响应:参与者收到
CanCommit
请求后,会根据自身情况判断是否可以执行事务。如果参与者认为可以执行事务,则返回Yes
响应,表示它准备好执行事务;如果参与者无法执行事务,例如因为资源不足、数据冲突等原因,则返回No
响应。 -
如果参与者能够执行任务,那么返回协调者
Yes
状态参与者不能执行任务,返回
No
,结束事务
预提交阶段(PreCommit)
- 执行事务操作:如果协调者在准备阶段收到了所有参与者的
Yes
响应,那么它会向所有参与者发送PreCommit
请求,进入预提交阶段。参与者在收到PreCommit
请求后,会执行事务操作,但不会真正提交事务,而是将事务操作结果记录到本地的事务日志中,并释放部分事务资源,但仍保持对事务的锁定状态,以便后续可能的提交或回滚操作。 - 响应预提交结果:参与者执行完事务操作后,会向协调者发送
Ack
响应,表示事务操作已经执行完成。如果参与者在执行事务操作过程中出现了问题,例如数据库故障、网络问题等,导致无法执行事务操作,那么它会向协调者发送No
响应,并回滚已经执行的事务操作。 - yes
-
提交 / 回滚阶段(DoCommit/Abort)
- 提交事务:如果协调者在预提交阶段收到了所有参与者的
Ack
响应,那么它会向所有参与者发送DoCommit
请求,通知参与者正式提交事务。参与者在收到DoCommit
请求后,会将事务正式提交到数据库中,并释放所有事务资源,完成事务操作。 - 回滚事务:如果协调者在准备阶段或预提交阶段收到了任何参与者的
No
响应,或者在等待参与者响应的过程中出现了超时等情况,那么它会向所有参与者发送Abort
请求,通知参与者回滚事务。参与者在收到Abort
请求后,会根据本地事务日志中的记录,回滚已经执行的事务操作,并释放所有事务资源。
三阶段提交协议相对于二阶段提交协议,增加了预提交阶段,使得分布式事务的提交过程更加稳健,能够在一定程度上避免数据不一致的问题,但它也增加了事务的复杂性和性能开销。
在分布式系统中,为了协调多个节点共同参与的事务,通常会采用三阶段提交协议(3PC)。关于三阶段提交协议,以下哪个描述是正确的?
A. 三阶段提交协议只包括准备提交(Prepare)和提交(Commit)两个阶段。
B. 在三阶段提交协议中,如果有一个参与者回复不能提交(No),则事务协调者会立即中止事务。
C. 三阶段提交协议可以确保在所有参与者都成功提交事务之前,任何参与者都不会单独提交事务。
D. 三阶段提交协议中的第三阶段是向所有参与者发送预提交(PreCommit)请求。
正确答案:
C
参考
分布式事务讲解之CAP,2PC,3PC,TCC,分布式锁 - 上善若泪 - 博客园 (cnblogs.com)