两阶段提交协议

两阶段提交协议(two phase commit protocal,2PC)是一种原子操作协议。它是协调分布式事务中的参与者,并决定提交或取消(回滚)的分布式算法。

在通常的两阶段提交协议中,系统一般包括两中角色,一类为协调者,另一类为事务参与者。 在分布式事务执行中,这个协议包括两个阶段:

  • 阶段1:提交请求阶段(commit-request phase,或称表决阶段,voting phase)

    在请求阶段,协调者通知所有的事务参与者准备提交或取消事务,然后进入表决过程,在表决过程中,参与者告诉协调者自己的决策:同意(如果事务参与者本地执行成功)或取消(如果事务参与者本地执行发生问题)

  • 阶段2:提交阶段(commit phase)

    在该阶段,协调者根据第一阶段投票结果进行决策,协调者决定是提交(只有当所有事务参与者都同意)还是取消事务,并将结果通知所有的事务参与者,事务参与者对本地的事务资源采取响应的动作。

在实际的业务场景中,例如请求插入一条数据,协调者将通知所有事务参与者。事务参与者创建事务,执行具体的插入操作,并返回自己的结果给协调者。而在具体的事务参与者上,插入操作并没有完成,还需要等待协调者发送通知,才能执行事务的commit或者rollback,这个依赖于是不是所有的事务参与者都成功执行了这个插入操作。

这个过程实现了数据的强一致性,然后缺点也很明显,2PC是一个堵塞型协议。如果协调者失败了,所有的事务参与者都永远无法结束他们的事务:当事务参与者将决策通知给协调者,它会一直堵塞,直到收到commit或者roolback的命令。

三阶段提交协议

三阶段提交协议(three phase commit protocal,3PC)与二阶段提交协议不同,它引入了超时机制,是非堵塞的。事务通过3PC提交时,持有的资源锁在超时之后会被释放。 在3PC中,系统分为不确定状态和确定状态。无论是协调者,还是事务参与者,当超时发生时或者接收到确定消息时,对应参与者都将有不确定状态进入确定状态,超时则代表对应参与者无法执行命令或执行失败,在确定状态下,3PC就变成2PC的问题了,这种情况不会发生事务永久等下去的情况。

我们可以参照一个经典的现实场景: 班长组织班级成员去爬长城:如果所有人都同意去爬长城,那么活动将举行;如果有一人不同意去爬长城,那么活动将取消。用3PC算法解决该问题的过程如下:

  • 阶段1(不确定状态):

    班长发邮件给B、C和D,提出下周六去爬山,问是否同意并要求所有同学最晚明天中午回复邮件,否则将默认为不同意。那么此时班长需要等待所有同学的邮件。

  • 阶段2(确定状态):

    第二天中午,班长登记所有结果,未答复同学的意见处理为不同意。

  • 阶段3(确定状态):

    如果班次班级活动要求所有人都能去,那么根据结果判定,如果有不同意或者未答复的,那么本次活动取消。而如果大多数人同意活动如期举行,那么根据统计的结果判定是否举行活动即可。

三阶段提交协议正是在二阶段提交协议的基础上引入了超时和状态机制,从而将异常的情况在一定条件下,依然转化为二阶段提交协议的场景来处理。

系统设计更多的是在我们实际生活的应用场景基础上演化而来的,立足于业务实际,可能产生更多的2PC协议的变种,来更好的解决我们遇到的问题。

Wiki链接:#####

https://en.wikipedia.org/wiki/Two-phase_commit_protocol

https://en.wikipedia.org/wiki/Three-phase_commit_protocol

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途
转载请保持完整性并注明来源链接