vlambda博客
学习文章列表

分布式事务方案:二阶段提交

分布式事务方案:

  • 二阶段提交

  • TCC协议

  • 异步确保型

  • 事务型消息


以上四种广为人知的是分布式事务的一致性解决方案,其中只有二阶段提交是可以保证对应的CAP原理当中的强一致性和分区容忍性,其余的三种都是保证了可用性和分区容错性。


二阶段提交

二阶段提交的实现方式



假设对应的分布式事务场景如下:



【交易系统】就是transaction Manager(TM),【商品系统】和【优惠券系统】分别是Server1和Server2。


在二阶段提交协议当中,我们引入了一个【事务协调者】的概念,一般把它称作【事务管理者】。第一阶段TM会分别向两个服务发送prepare请求,两个服务会对应开启本地事务并执行,执行完毕会有ack回馈,告诉TM回滚的操作成功;TM需要收到两个服务的ack确认,才会向两个服务发起commit操作。只有这样才算完成事务。

鉴于二阶段提交是强一致性的,如果二阶段提交还没完成(还没commit),这个时候有Client来读取对应的服务,因为对应数据在prepare阶段是加了排它锁的,所以读取时就会阻塞住。只有commit之后才会释放perpare阶段的锁;亦或者服务还没commit就挂掉了,那服务重启之后就会去redo log回放prepare阶段的操作,然后锁死对应的数据,到TM反查当前事务是否需要重发commit,同样还没commit,对应的数据就没法被读取。


基于实现方式,【二阶段提交】的性能是比较差的,如果分布式参与者越多,意味着不可用的时间可能会更长,所以在互联网实际场景中比较少用。


有优化的空间吗?这就不得不提到一个中间件Zookeeper,它是分布式的,在数据同步这块也是分布式事务。整个集群会有一个Leader跟多个Follower,它数据同步是通过【二阶段提交】外加【Raft同步】(要求超过一半以上的节点同步成功即可算写成功)实现的。


既然只需要一半以上,那就会有Follower同步失败的可能,Zookeeper选举机制也是基于Raft,超过一半的节点认为你的数据是最新的,那么你就有资格成为Leader(具体的选举细节不止这么简单,详情了解下面的资料),选出Leader之后会进行数据同步,把Leader最新的数据和日志同步到Follower中,当半数以上的Follower同步数据成功后Leader才能成为真正的Leader,就可以处理事务请求了,之前同步失败的Follower也能同步回来。


ZooKeeper 的 Leader 选举 + ZooKeeper 集群的数据同步