News & Insights

搞活动超卖了三百件,后端系统开发的库存并发难题

促销开始五分钟超卖三百件,赔了违约金还伤了客户。库存超卖是后端系统开发最经典的并发问题:查库存和扣库存两步不原子,高并发下人人读到有货。本文给出从数据库原子扣减、乐观锁到Redis预扣的递进解法,并提醒支付超时释放库存的兜底设计。

搞活动超卖了三百件,后端系统开发的库存并发难题

一家做母婴用品的客户搞了个限时促销,开场五分钟客服就炸了:下单成功的订单比库存多出三百件。紧急下架、挨个道歉、赔违约金,一场促销变成一场危机。问题出在哪?查库存和扣库存是两步操作,平时人少没事,高并发下几百个请求同时读到还剩十件,人人都以为自己抢到了。这是后端系统开发最经典的并发考题,答案其实有一套递进方案。

最简单的一招就很有效

把两步并成一步:不用先查再扣,直接一条更新语句解决——扣减库存时带上条件,库存大于等于购买数量才允许更新。这条语句在数据库里是原子操作,一百个请求并发进来,数据库排队执行,谁也不多扣。多数中小系统的秒杀场景,光这一招就够用,根本不需要什么高深架构。很多人低估了数据库单行的处理能力,一台普通服务器每秒处理几百上千次这样的更新不成问题。

并发再往上走怎么办

  • 乐观锁:表里加个版本号字段,更新时核对版本,改过的请求重新读取再试,适合冲突没激烈到秒杀级别的场景;
  • Redis预扣:真有大促量级的,把库存提前放进Redis,请求先在Redis里原子扣减,扣成功的再异步落库,数据库只承担涓涓细流;
  • 限流排队:请求先在入口排队,超出库存量的直接告知已抢完,让后面的流量根本不碰库存逻辑。

方案从上到下成本递增,按真实并发量选,别为一个日订单两百的店上Redis集群,杀鸡用牛刀的钱不值得花。

还有个常被漏掉的尾巴:下单成功不等于成交。用户拍了不付款的占相当比例,库存被占着,别人买不到。要配支付超时释放:三十分钟未付款自动取消订单、库存回滚。释放逻辑也要防并发——取消订单和用户恰好完成支付撞车的极端情况,用订单状态做原子判断,先到先得。超卖防住了,少卖同样要防,两头都是钱。

那位母婴客户的后续处理是个正面样本:修复用了原子扣减加超时释放,下一次促销前主动做了一轮并发测试,模拟五百人同时抢十件库存,实测成交正好十件。预案做在活动前,才叫预案。

超卖的背面是少卖

防住超卖只是及格线,库存管理还有另一头:付款超时及时释放,取消订单准确回滚,活动结束后对一遍账。后端系统开发里库存模块的完整度,往往在一次活动里就见分晓,平时看不出差别,高峰当天全是分水岭。

两条建议:有秒杀、限量、拼团这类玩法的,立项时就把并发场景告诉技术方,让方案里写明扣减方式;每次大促前做一轮真实的并发模拟测试,比格网络帮客户做大促护航时这叫抢购演练,演练通过的促销才敢开闸,活动的口碑经不起超卖一次。

分享这篇文章:

准备好开启您的数字化之旅了吗?

让我们一起打造专业、高效、可增长的企业官网

✓ 链接已复制到剪贴板
电话咨询 免费咨询 获取方案
跳转咨询表单 免费获取方案 18942912117 在线咨询