3PC三阶段提交

本文详细解读了3PC(三阶段提交协议)在分布式系统中的工作流程,包括CanCommit阶段的询问、PreCommit阶段的预提交与中断决策,以及doCommit阶段的提交与回滚。重点讨论了其优点与网络分区导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三阶段提交示意图

阶段一:CanCommit

  1. 事务询问。协调者向所有参与者发送包含事务内容的canCommit的请求,询问是否可以执行事务提交,并等待应答;
  2. 各参与者反馈事务询问。正常情况下,如果参与者认为可以顺利执行事务,则返回Yes,否则返回No。

阶段二:PreCommit

        在本阶段,协调者会根据上一阶段的反馈情况来决定是否可以执行事务的PreCommit操作。有以下两种可能:

执行事务预提交

  1. 发送预提交请求。协调者向所有节点发出PreCommit请求,并进入prepared阶段;
  2. 事务预提交。参与者收到PreCommit请求后,会执行事务操作,并将Undo和Redo日志写入本机事务日志;
  3. 各参与者成功执行事务操作,同时将反馈以Ack响应形式发送给协调者,同事等待最终的Commit或Abort指令。

中断事务
        假如任意一个参与者向协调者发送No响应,或者等待超时,协调者在没有得到所有参与者响应时,即可以中断事务:

  1. 发送中断请求。 协调者向所有参与者发送Abort请求;
  2. 中断事务。无论是收到协调者的Abort请求,还是等待协调者请求过程中出现超时,参与者都会中断事务;

阶段三:doCommit

        在这个阶段,会真正的进行事务提交,同样存在两种可能。

执行提交

  1. 发送提交请求。假如协调者收到了所有参与者的Ack响应,那么将从预提交转换到提交状态,并向所有参与者,发送doCommit请求;
  2. 事务提交。参与者收到doCommit请求后,会正式执行事务提交操作,并在完成提交操作后释放占用资源;
  3. 反馈事务提交结果。参与者将在完成事务提交后,向协调者发送Ack消息;
  4. 完成事务。协调者接收到所有参与者的Ack消息后,完成事务。

中断事务
        在该阶段,假设正常状态的协调者接收到任一个参与者发送的No响应,或在超时时间内,仍旧没收到反馈消息,就会中断事务:

  1. 发送中断请求。协调者向所有的参与者发送abort请求;
  2. 事务回滚。参与者收到abort请求后,会利用阶段二中的Undo消息执行事务回滚,并在完成回滚后释放占用资源;
  3. 反馈事务回滚结果。参与者在完成回滚后向协调者发送Ack消息;
  4. 中端事务。协调者接收到所有参与者反馈的Ack消息后,完成事务中断。

3PC的优缺点

        3PC有效降低了2PC带来的参与者阻塞范围,并且能够在出现单点故障后继续达成一致;
        但3PC带来了新的问题,在参与者收到preCommit消息后,如果网络出现分区,协调者和参与者无法进行后续的通信,这种情况下,参与者在等待超时后,依旧会执行事务提交,这样会导致数据的不一致。

### 两阶段提交协议与三阶段提交协议的工作原理 #### 两阶段提交协议 (2PC) 两阶段提交协议涉及两类主要角色:协调者(Coordinator)和参与者(Participant),其中协调者负责整个分布式事务的提交过程,而参与者则执行具体的事务操作并向协调者汇报结果[^1]。 该协议分为准备阶段和提交阶段: - **准备阶段**:协调者向所有参与者发送`prepare`消息,询问是否可以提交事务。如果所有参与者均回复同意,则进入下一阶段;若有任意一个参与者拒绝或未响应超时,则取消整个事务。 - **提交阶段**:当所有参与者都准备好后,协调者会发出最终决定——要么是全局提交命令,即让各节点真正提交其本地更改;要么是回滚指令,指示撤销之前所做的准备工作。此过程中任何一步失败都将触发回滚流程以保持系统的整体一致性状态[^4]。 ```python def two_phase_commit(coordinator, participants): try: # 准备阶段 for p in participants: response = coordinator.send_prepare(p) if not response.is_ok(): raise Exception("Prepare failed") # 提交阶段 for p in participants: coordinator.send_commit(p) except Exception as e: for p in participants: coordinator.send_rollback(p) ``` #### 三阶段提交协议 (3PC) 为了克服2PC存在的某些局限性,比如长时间等待以及单点故障风险等问题,提出了改进版的三阶段提交协议。相比前者增加了预提交阶段,并允许部分成员提前得知最终决策,从而减少了不确定期间内的资源锁定时间[^2]。 具体来说,3PC包含三个阶段: - **CanCommit 阶段**:协调者先发起一轮询问,确认是否有足够的条件继续进行后续步骤。只有当所有参与方都能保证能够顺利完成之后的操作才会进入到下一个PreCommit阶段; - **PreCommit 阶段**:一旦收到肯定答复,协调者便通知各个站点做好预备工作,但此时并不立即生效变更。这一轮交互结束后,即使网络暂时中断也不会影响到已经达成的一致意见; - **DoCommit 或 Abort 阶段**:最后由协调者广播真正的提交还是终止的消息给所有的参与者去同步执行相应的动作。这种方式有效地降低了因中途出现问题而导致的数据不一致的风险。 ```python def three_phase_commit(coordinator, participants): try: # CanCommit阶段 can_commit_responses = [] for p in participants: response = coordinator.ask_can_commit(p) can_commit_responses.append(response) all_agree = all([r.is_yes() for r in can_commit_responses]) if not all_agree: return # PreCommit阶段 precommit_responses = [] for p in participants: response = coordinator.pre_commit(p) precommit_responses.append(response) final_decision = "COMMIT" if all([r.is_ready() for r in precommit_responses]) else "ABORT" # DoCommit/Abort阶段 for p in participants: coordinator.finalize_transaction(p, final_decision) except Exception as e: handle_exception(e) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值