
1) 【一句话结论】:在订阅续费场景,采用Saga模式结合消息队列异步解耦,通过分步骤本地事务与补偿机制实现最终一致性,并设计幂等性避免重试问题,适用于跨服务、异步的业务流程。
2) 【原理/概念讲解】:分布式事务的核心是跨服务数据一致性,传统两阶段提交(2PC)强一致但阻塞,不适合异步场景。Saga模式将长事务拆为多个本地事务,每个步骤独立执行,通过消息队列(如Kafka)按顺序传递步骤状态。若某步骤失败,触发补偿步骤回滚至一致状态。类比:订餐流程,点餐(支付)、准备餐(数据库更新状态)、通知取餐(消息通知),若准备餐失败,触发“取消准备”补偿,恢复原状态,类似Saga的补偿机制。
3) 【对比与适用场景】:
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 两阶段提交(2PC) | 强一致性,协调者控制所有参与者 | 阻塞,所有参与者必须响应 | 金融核心、强一致性要求高的场景(如银行转账) | 阻塞风险,网络故障可能导致事务失败 |
| Saga模式 | 最终一致性,通过本地事务+补偿步骤 | 异步,步骤独立 | 业务流程长、跨服务、需要解耦的场景(如订阅续费、订单处理) | 需要补偿逻辑,可能存在部分步骤失败导致不一致 |
4) 【示例】:订阅续费流程步骤:
UPDATE user_subscription
SET status = 'active', payment_status = 'paid'
WHERE user_id = ? AND subscription_id = ?
AND status = 'pending'; -- 幂等性检查,避免重复更新
若更新成功,发送“订阅激活”消息到Kafka(主题:subscription-activate)。UPDATE user_subscription
SET status = 'pending', payment_status = 'failed'
WHERE user_id = ? AND subscription_id = ?
AND status = 'active'; -- 检查当前状态是否为active,避免重复回滚
幂等性示例:数据库更新时,先检查当前订阅状态是否为“pending”,若已为“active”则跳过,避免重复更新。
5) 【面试口播版答案】:在万兴的订阅续费流程中,我们采用Saga模式结合消息队列实现分布式事务。具体来说,流程分三步:支付服务处理支付后,发送支付成功消息到Kafka;数据库服务消费后更新用户订阅状态,再发送激活消息;通知服务消费后发送通知。如果某步骤失败,Saga会通过补偿消息回滚,比如支付失败则让数据库回滚。同时,每个消息处理步骤都设计幂等性,比如数据库更新时检查状态,避免重试时重复更新,确保数据一致性。
6) 【追问清单】:
7) 【常见坑/雷区】: