一句话总结:2PC两阶段提交协议应用于分布式事务场景,解决分布式多个系统间数据的一致性,如数据库XA机制。
背景:
假设有两个系统A和B,同一个原子业务,举个常用的转账例子,A系统加1000元,B系统相应减1000元,这时若A执行成功了,B执行失败了,对业务来说肯定出问题了。这里的问题出在系统A不感知B的状态,B也不感知A。对于分布式系统,需要一个协调者来感知每个系统的执行状态。这个协调者可以由应用或数据库/缓存的Agent来承担都可以。
2PC两阶段提交协议:
大家不要将两阶段提交想的复杂,事实上,这个协议很简单,prepare阶段参与者只是执行事务,但不提交,此时已能知道能否成功执行,并将此状态反馈给协调者。协调者收到都成功,则通知所有参与者commit。若只要有一个反馈失败,则通知所有参与者rollback。协调者在commit阶段发出commit或rollback通知后就不管了。
延伸思考:
上面描述的是正常流程,生产环境还要全面考虑各种异常场景。
1、协调者节点挂了
此场景比较主流的方案是选举机制,首次即通过选举决定谁是协调者,当协调者挂掉后重新选举。
2、commit阶段出现部分失败
2PC协议在commit阶段发出commit或rollback通知后就不管了,若此时由于网络或系统原因,A执行commit/rollback成功,B执行失败,还是会出现数据不一致。此场景就需要考虑3PC、另一个独立Agent进程、超时机制等来确保事务无论如何都会被执行。
备注:网上很多有说一个问题是同步阻塞,性能不行。我觉得大多数场景特别是针对事务数据一致性的场景对性能要求并不高,不该把这个作为问题。毕竟做12306、微信、抖音、王者荣耀等这些高并发实时性强项目的场景不多,普通数千并发实时要求也不强以当前服务器性能完全hold的住的。
引用:
https://en.wikipedia.org/wiki/Two-phase_commit_protocol
注:图片来源于网络,侵删。