
1) 【一句话结论】
在支持PC和移动端的高并发商城系统中,最大技术挑战是支付与库存扣减的原子性及一致性,通过分布式锁保证库存扣减的原子性、消息队列实现支付异步处理,结合事务管理确保最终一致性,显著降低超卖风险。
2) 【原理/概念讲解】
高并发下单时,用户操作流程是:库存扣减→支付扣款。若库存扣减成功但支付失败,库存无法回滚会导致超卖(类似超市收银员扫描商品后库存减少,支付失败需恢复库存,高并发下多个请求同时处理,导致库存被扣减后支付失败,库存无法回滚)。解决方案需保证库存扣减的原子性(扣减成功则支付,失败则回滚),支付环节异步处理,避免阻塞主流程。
3) 【对比与适用场景】
| 对比项 | 分布式锁(Redis) | 数据库事务(本地锁) |
|---|---|---|
| 定义 | 利用Redis的SETNX命令实现多进程/服务器间的互斥 | 数据库的BEGIN...COMMIT/ROLLBACK,保证单数据库内操作原子性 |
| 特性 | 跨进程/服务器,支持高并发,需设置过期时间防止死锁 | 仅限单数据库,性能较高,但无法跨分布式系统 |
| 使用场景 | 分布式系统中的资源互斥(如库存扣减) | 单机或单数据库内的操作(如订单创建) |
| 注意点 | 过期时间需大于业务处理时间+网络延迟缓冲(如业务处理2秒,设置5秒锁过期时间) | 事务隔离级别需正确设置(如READ COMMITTED),避免脏读、幻读 |
4) 【示例】
分布式锁实现(考虑网络延迟,设置锁过期时间):
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
lock_key = f"stock:{product_id}"
lock_timeout = 5 # 锁过期时间(业务处理时间2秒+缓冲3秒)
def deduct_stock(product_id, quantity):
with r.lock(key=lock_key, timeout=lock_timeout):
stock = r.get(f"stock:{product_id}")
if stock is None or int(stock) < quantity:
return False
new_stock = int(stock) - quantity
r.set(f"stock:{product_id}", str(new_stock))
return True
# 示例调用
product_id = 1001
quantity = 1
if deduct_stock(product_id, quantity):
print("库存扣减成功")
else:
print("库存不足")
消息队列回滚机制(支付失败后库存回滚):
5) 【面试口播版答案】
之前参与的多益网络商城系统,支持PC和移动端,核心挑战是高并发下单时库存扣减与支付结果不一致导致的超卖问题。解决方案是分两步:首先用Redis分布式锁保证库存扣减的原子性,避免多个请求同时扣减同一商品库存;其次支付环节采用异步消息队列(如RabbitMQ),库存扣减成功后发送支付请求,支付失败时消费者处理失败消息,触发库存回滚,确保最终一致性,性能测试中超卖率从0.5%降至0.01%,有效降低风险。
6) 【追问清单】
7) 【常见坑/雷区】