分布式事务两阶段提交(2PC)的思考

关于分布式事务的设计,我们一直在使用两阶段提交(2PC)作为标准的流程。但是有必要从本质上理解为什么需要两阶段提交(有兴趣的同学可以看看这篇文章http://duanple.blog.163.com/blog/static/70971767201311810939564)


首先我们要清楚事务的流程是什么样的,一个事务最基本的流程为:读写操作,redo/undo log,写数据库表。也就是说在真正在数据库表之前,要有redo/undo log操作。在传统的分布式事务设计中,redo/undo log放在两阶段提交的第一阶段中,如果第一阶段成功,则进行第二阶段的数据库表更新。


这里有人要问,上述过程和单机版事务有什么区别,为什么单机版事务没有两阶段提交一说。我的回答是,单机版事务也把redo/undo log操作放在提交阶段,但是其是和数据库表的更新连起来一块做了。其最本质的区别是分布式事务必须要在提交阶段分开log操作和数据库表操作,否则某一个节点成功,另一个节点失败,就会造成数据的不一致。


上述就是两阶段提交的本质。有人说两阶段提交是为了降低网络通信危险期对系统影响。其定义的危险期(in-dout time)是指网络通信的时间,因为分布式事务每个node都需要做相应工作,如果最后提交时又要写log,又要管理lock,又要最后commit标记,事情太多。这么长的时间会使得某个节点的网络通信失败的概率加大,所以把大块的任务划分为小块,即分成了2阶段提交。通过本文的解释,可以看出这种说法是错误的。


那么我们再进一步思考,两阶段提交带来的性能影响就是多了一轮RPC,如果我们的目标是去掉2PC或者优化2PC,本质目标就是减少RPC。如果我们能用多版本机制实现undo log,那么提交阶段如果能把redo和数据库表操作放在一起就可以省掉第一阶段提交了,但是这样不能避免出错的问题。redo log 应该放在commit之前,那么能否每次读写操作的时候也同时进行redo log操作呢?传统的做法redo log和undo log都在放在所有读写操作完成之后,commit之前进行,其目的是如果abort的话就不需要redo log,当然也不需要写表了。带来的缺陷是给分布式事务多了一轮RPC。如果我们每次读写操作都带上redo log同时写入各自版本,那么就不需要两阶段提交(省掉一轮RPC)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值