
1) 【一句话结论】为验证订单成功但库存未扣减的分布式事务异常,需设计基于故障注入的测试方案,结合Seata Saga补偿机制,通过模拟库存扣减失败并触发补偿流程,验证事务一致性,利用分布式日志链路定位故障点,最终修复补偿逻辑。
2) 【原理/概念讲解】分布式事务的核心是跨服务(订单、库存、支付)的原子性保证。当系统规模扩大,传统事务无法覆盖时,引入Seata Saga(链式补偿事务)。Saga模式中,每个步骤(如库存扣减、支付扣款)是本地事务,若失败则触发补偿事务(如库存回滚、订单取消、支付退款),保证最终一致性。“订单成功但库存未扣减”异常源于补偿事务失败(如补偿逻辑错误或故障处理不当)。类比银行跨行转账:若网络中断导致一方扣款成功但另一方未到账,银行通过清算(补偿)恢复一致性。Saga中,订单创建成功(本地事务),库存扣减失败(触发补偿),若补偿失败,库存未回滚,订单状态未回滚,支付未退款,导致不一致。
3) 【对比与适用场景】
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Seata Saga(快手电商实际采用) | 基于本地事务的链式补偿事务 | 最终一致性,无阻塞,支持幂等 | 电商订单(库存、支付、订单状态) | 需配置事务组,补偿失败需人工干预或自动重试,需保证补偿逻辑幂等 |
| 两阶段提交(2PC) | 领导者协调参与者 | 强一致性,阻塞严重 | 银行核心交易(低延迟) | 网络故障易导致阻塞,性能低 |
| TCC模式 | 事务补偿(Try/Confirm/Cancel) | 最终一致性,无阻塞 | 需频繁补偿的场景 | 代码复杂,需幂等,业务逻辑耦合 |
| 最终一致性(无事务) | 无事务协调 | 低延迟,高可用 | 数据库分库分表后的读操作 | 无法保证事务原子性,需业务逻辑处理 |
4) 【示例】
测试用例步骤:
1. 下单请求:
POST /order-service/create-order
{
"userId": 1001,
"productId": 123,
"quantity": 2,
"amount": 200
}
响应:订单ID=1001,状态=待支付。
2. 故障注入(库存扣减失败):
模拟调用库存服务:
POST /inventory-service/deduct
{
"orderId": 1001,
"productId": 123,
"quantity": 2
}
响应:错误码500,超时(模拟网络故障)。
3. 支付扣款成功:
POST /payment-service/charge
{
"orderId": 1001,
"amount": 200
}
响应:支付成功,状态=已支付。
4. 补偿验证:
- 检查订单状态:订单ID=1001状态是否为“待支付”(Seata触发订单取消补偿)。
- 检查库存日志:库存扣减失败记录,库存数量增加2。
- 检查支付日志:退款记录,资金退回用户账户。
结果:若状态回滚、库存回滚、支付退款,补偿成功;否则,补偿逻辑失效。
5) 【面试口播版答案】面试官,您好。为验证订单成功但库存未扣减的分布式事务异常,我会设计一个基于故障注入的测试方案,结合快手电商采用的Seata Saga补偿机制。具体来说,我会模拟用户下单后,库存扣减服务因网络故障超时失败,同时支付扣款正常完成。通过监控订单状态变化(从“待支付”变为“待支付”回滚状态)和库存系统日志,确认补偿是否生效。然后,定位问题:通过分布式链路追踪(如SkyWalking)关联订单、库存、支付三个服务的日志,找到库存服务网络中断的根源。解决措施包括优化库存服务重试策略(如指数退避),或增强Saga补偿逻辑的幂等性检查。核心是通过模拟故障场景,验证补偿逻辑的有效性,并通过日志和监控定位问题,最终修复事务一致性。
6) 【追问清单】
7) 【常见坑/雷区】