← 返回博客
2026-08-14 16:42:27

面试必问:分布式事务与CAP取舍,别再背Base理论了

面试必问:分布式事务与CAP取舍,别再背Base理论了

【难度:★★★】【频率:高频】【适用:2-5年】

从一个订单扣库存的“事故”说起

面试官翻开简历,看到“负责订单系统”几个字,目光一凛:“假设用户下单支付成功,但库存扣减失败,订单却是已支付状态。这笔钱怎么退?库存怎么补?系统怎么保证最终一致?”

这个问题不是凭空刁难。支付成功与库存扣减分属不同服务,甚至不同数据库,本地事务鞭长莫及。面试官真正想看的是:候选人是否经历过分布式下的数据不一致,是否理解一致性不是“非黑即白”,而是有代价的取舍。

面试官问:支付成功,库存扣减失败,如何保证最终一致?

为什么这么问

考察三个层次:第一,是否理解分布式事务的适用边界;第二,是否掌握主流方案(2PC、TCC、本地消息表、MQ事务消息)的优劣;第三,是否具备CAP理论指导下的工程判断力——知道什么时候该用强一致,什么时候该用最终一致。

怎么回答

回答分三步走,先定调,再给方案,最后落到项目。

第一步:定调——明确这是“跨服务数据一致性”问题,本地事务无法解决。

第二步:给方案对比,按一致性强度从强到弱排列。

第三步:落项目——结合具体场景选型。

以电商下单为例,支付成功与扣库存之间允许短暂不一致,但必须最终一致。因此选用MQ事务消息方案:订单服务发半消息,执行本地事务(订单状态改为已支付),commit后库存服务消费消息扣减库存。若库存服务宕机,MQ重试;重试多次失败,则进入死信队列,由定时任务扫描补偿(人工或自动退款)。

怎么拓展:一个让面试官眼前一亮的深度点

“TCC的空回滚与悬挂问题”是比方案本身更值钱的细节。

空回滚:Try未执行,但Cancel却先到了(比如网络超时后Try请求丢失)。此时Cancel要能识别并直接返回成功,否则会报错。悬挂:Try执行了,但Cancel先于Try到达(网络乱序),导致Try执行后无人管。解决方式是记录事务状态,Cancel到达时若发现Try未执行,则标记“已取消”,Try执行时发现标记则不再执行。

能主动抛出这两个细节,说明真正写过TCC,而非只背了概念。

可能追问

接法:解释半消息对消费者不可见,只有commit后才可见;broker会主动回查本地事务状态,保证消息不丢失。

接法:用唯一业务ID(订单号)做去重表,或利用数据库唯一索引,消费前先查后插。

接法:本地事务里写业务表和消息表,定时任务扫消息表发MQ,收到ACK后改状态。对比MQ事务消息,本地消息表需要自己实现扫描与重试,但更可控。

从CAP到取舍:为什么不能既要又要

问题自然延伸:既然方案这么多,选型的底层依据是什么?这就绕不开CAP理论——一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)三者不可兼得。分布式系统必须满足P(网络分区不可避免),所以真正的取舍在C和A之间。

关键理解:CAP不是“三选二”,而是“P必选,C和A在分区发生时只能选一个”。 2PC偏向CP,牺牲部分可用性(协调者故障则阻塞);MQ最终一致偏向AP,分区时仍可用,但数据可能短暂不一致。

工程判断力:核心资金链路选CP(如转账),非核心链路选AP(如积分、通知)。没有银弹,只有权衡。回答时点出“最终一致不是放弃一致性,而是通过补偿机制达到最终状态”,比空背“Base理论”高出一个段位。

面试实战:怎么把项目讲出分布式味道

简历写“负责订单系统”,面试官默认有分布式场景。讲项目时主动带出“订单状态与库存扣减的最终一致”案例,用STAR法则:

HR面提醒:被问“遇到的最大挑战”时,把上述案例包装成“如何解决跨服务一致性问题”,既展示技术深度,又体现责任心(主动做补偿兜底)。

总结

分布式事务没有标准答案,只有场景适配。核心收获有三点:一是理解2PC/TCC/MQ事务消息的适用边界;二是掌握CAP的底层取舍逻辑;三是能在项目中用具体案例证明思考深度。下一步行动建议:找一段真实代码(如RocketMQ事务消息demo),把半消息机制和回查逻辑手写一遍,面试时能画出时序图,比背十遍概念都管用。

本文关键词:分布式事务、CAP、TCC、MQ事务消息、最终一致