到底什么是“二阶段提交协议(2PC)”?下面的内容摘录自《从Paxos到Zookeeper——分布式一致性原理与实践》。
顾名思义,二阶段提交协议是将事务的提交过程分成了两个阶段来进行处理,其执行流程如下。
阶段一:提交事务请求
- 事务询问。
协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。- 执行事务。
各参与者节点执行事务操作,并将Undo和Redo信息记入事务日志中。- 各参与者向协调者反馈事务询问的响应。
如果参与者成功执行了事务操作,那么久反馈给协调者Yes响应,表示事务可以执行;如果参与者没有成功执行事务,那么就反馈给协调者No响应,表示事务不可以执行。
注意:此刻,各个参与者还未提交,即未Commit。上述第2条容易引起歧义,可能被误理解为Commit事务呢,其实不是。我们的理解应该是做一系列增删改查操作,加上某些业务逻辑判断(例如:帐户余额不得少于转账金额等),如果这些都OK,即满足了上述第3条中的“如果参与者成功执行了事务操作”。此刻,就差最后的临门一脚,即Commit。
阶段二:执行事务提交
在阶段二中,协调者会根据各参与者的反馈情况来决定最终是否可以进行事务提交操作,正确情况下,包含以下两种情况。
执行事务提交
假设协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务提交。
- 发送提交请求。
协调者向所有的参与者节点发送Commit请求。- 事务提交。
参与者接收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。- 反馈事务提交结果。
参与者在完成事务提交之后,向协调者发送Ack消息。- 完成事务。
协调者接收到所有参与者反馈的Ack消息后,完成事务。中断事务
假设任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无发接收到所有参与者的反馈响应,那么就会中断事务。
- 发送回滚请求。
协调者向所有参与者节点发出Rollback请求。- 事务回滚。
参与者接收到Rollback请求后,会利用其在阶段一中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。- 反馈事务回滚结果。
参与者在完成事务回滚之后,向协调者发生Ack消息。- 中断事务。
协调者收到所有参与者反馈的Ack消息后,完成事务中断。