题目
设计高并发电商场景下跨服务订单与库存的分布式事务方案
信息
- 类型:问答
- 难度:⭐⭐⭐
考点
分布式事务模式选型, 数据一致性保证, 异常处理机制, 性能与扩展性设计
快速回答
在电商高并发场景下,推荐采用Saga模式结合异步补偿机制:
- 使用事件驱动的Saga协调服务间事务
- 订单服务先创建状态为PENDING的订单
- 库存服务采用预扣库存策略
- 通过补偿事务处理失败场景
- 引入消息队列实现最终一致性
- 添加幂等性设计和重试机制
1. 问题场景分析
电商系统中创建订单涉及:
订单服务(创建订单记录)
库存服务(扣减商品库存)
支付服务(处理支付)
要求保证:订单创建与库存操作的原子性,同时支撑每秒10K+并发。
2. 核心解决方案:Saga模式
执行流程:
- 订单服务创建状态为PENDING的订单,发布ORDER_CREATED事件
- 库存服务监听事件,执行预扣库存(status=PRE_DEDUCT)
- 支付服务处理支付,成功后更新订单状态
- 库存服务确认最终扣减
补偿机制:
// Saga协调器伪代码
try {
orderService.createPendingOrder();
inventoryService.preDeductStock();
paymentService.processPayment();
orderService.confirmOrder();
inventoryService.confirmDeduction();
} catch (Exception ex) {
// 逆向补偿
paymentService.cancelPayment();
inventoryService.compensateStock(); // 恢复预扣库存
orderService.cancelOrder();
}3. 关键设计细节
3.1 数据一致性保障
- 最终一致性:通过消息队列(如Kafka)传递事件
- 幂等性设计:每个服务需实现幂等接口
// 库存服务幂等示例 @Transactional public void deductStock(String orderId) { if (deductionLog.exists(orderId)) return; // 已处理则跳过 // 扣减逻辑... }
3.2 异常处理
- 超时管理:设置Saga事务超时(如30s)
- 重试策略:指数退避重试(1s, 2s, 4s...)
- 人工干预:持久化事务日志供人工修复
3.3 性能优化
- 预扣库存:避免长期占用数据库锁
- 异步处理:非核心步骤(如通知)异步化
- 批量处理:库存扣减支持批量操作
4. 对比其他方案
| 方案 | 适用场景 | 本场景缺点 |
|---|---|---|
| 2PC | 低并发强一致 | 数据库锁导致性能瓶颈 |
| TCC | 金融等高一致 | 开发复杂度高,需预留资源 |
| 本地消息表 | 中低并发 | 消息表导致数据库压力 |
5. 最佳实践
- 监控:实现Saga可视化跟踪器
- 隔离性:库存服务采用版本号避免超卖
UPDATE inventory SET stock = stock - 1, version = version + 1 WHERE product_id = ? AND version = ? - 降级方案:库存不足时快速失败
6. 常见错误
- ❌ 未处理网络分区导致的状态不一致
- ❌ 补偿事务未实现幂等(导致重复回滚)
- ❌ 忽略事务日志持久化(故障后无法恢复)
- ❌ 未设置事务超时(资源长期锁定)
7. 扩展知识
- Seata框架:AT/Saga模式实现
- CDC技术:通过Debezium捕获数据库变更
- Saga编排模式:Choreography vs Orchestration
- 跨服务追踪:集成OpenTelemetry实现全链路监控