星巴克不适用两阶段提交 Gregor Hohpe 之 异常处理

      在异步消息处理的模式中,异常处理是个难点。如果您相信实践出真知的话,那么不妨参考一下星巴克是如何处理异常的:如果您无法付账,那么他们会在饮料已经冲调完成的情况下把饮料倒掉,否则就直接吧杯子从队列中拿出来;如果他们把饮料弄错了,或者您觉得不合口味,那么他们会为您重新冲调;如果机器坏了,他们根本无法冲调咖啡,那么他们会把钱退给您。上述的每一个场景都描述了一种不同但十分有趣的异常处理策略:

 

一笔勾销  这种对错误的处理策略最为简单:什么也不做,或者将已经做完的全部作废。尽管听上去不是什么好主意,但在现实中这种做法还是可以接受的。如果损失不大,那么建立一种纠错方案所花费的代价可能要比就此罢休更加高昂。以我曾经工作过的几家ISP供应商为例,在处理计费/服务周期不一致的问题时,他们采用的就是这个办法。他们的客户有可能在被收费之前就把服务取消,但由于这种损失不大,所以不会影响到公司的正常运营。他们会定期根据报表查出这些“免费”的帐户,然后将其关闭。

 

重试   当操作集合(也就是“事务”)中的某一步失败时,我们有两种选择:一个就是将所有完成的操作撤销;而另一个则是重试失败的那步操作。如果失败的操作重新提交后确实有成功的可能,那么重试还是一个不错的选择。例如,如果失败的原因是违反了业务规则,那么重试就不太可能管用;而如果失败的原因只是外部的系统暂时不可用,那么重试则是很有可能成功。此外,采用Idempotent Receiver的重试方案是一个特例。在这种情况下,我们可以简单的将所有的操作重新提交,因为 Idempotent Receiver 会忽略重复的消息。

 

补救   最后一个选择就是把所有已经完成的操作撤销,并将系统恢复到原先的状态。这种“补救措施”很有效,例如在处理财务系统遇到问题时,我们可以把已经扣的钱重新存到帐户上。


      而两阶段提交不同于上述这些策略,它需要依赖互相分离的准备阶段与执行阶段。还是以星巴克为例,如果他们采用两阶段提交,哪么顾客需要把钱放在收银台上并等在那里,而收银员则需要把收据准备好;然后冲调师再把冲调完成的饮料也放在收银台之上;最后大家在一瞬间同时出手,交换钱、收据和饮料。无论是收银员还是顾客,在“事务”完成之前都不能离开。这种两阶段提交方式一定会让星巴克破产,因为该方法必然使得他们在单位时间内接待顾客的数量急剧下降。这个例子很好的说明了,尽管两阶段提交能把生活变得十分简单,但是由于它要求在多个异步操作的序列间维持事务资源的一定状态,因此,它阻碍了消息的自由传递(也就等于损害了可伸缩性)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值