未支付订单如何释放库存
在电商或交易系统中,处理未支付订单的库存释放是典型的高并发场景问题。以下是结合 Java 技术栈的完整解决方案,涵盖 设计思路、技术实现、容错机制,并基于实际项目经验(如标易行平台的标书资源预约场景)进行分析:
一、核心设计原则
- 最终一致性:确保库存释放与订单状态的最终一致,允许短暂超卖但最终正确。
- 高并发安全:避免超卖(多个用户同时释放库存导致负数)或库存未释放(用户未支付但库存未回退)。
- 可扩展性:支持海量订单和库存操作的横向扩展。
二、技术方案与实现
方案 1:延迟消息 + 事务回查(主流方案)
适用场景:实时性要求高(如 15 分钟内未支付自动释放)。
实现步骤
-
下单扣减库存:
@Transactional public void createOrder(OrderDTO order) {// 1. 扣减库存(数据库乐观锁或 Redis Lua 原子操作)int affectedRows = productMapper.reduceStock(order.getSkuId(), order.getQuantity());if (affectedRows == 0) {throw new BusinessException("库存不足");}// 2. 创建订单(状态为未支付)Order orderEntity = convertToEntity(order);orderMapper.insert(orderEntity);// 3. 发送延迟消息(RabbitMQ 死信队列或 RocketMQ 延迟消息)Message message = new Message("ORDER_DELAY_TOPIC"