秒杀库存必须用redis原子decr实现,先同步库存到redis(如set sku:2001:stock 100),再执行decr扣减;若返回值

在PHP电商系统中实现秒杀功能时,必须确保同一商品的库存扣减操作不可被并发请求打断,否则100件库存可能被卖出105件。直接用PHP读取再更新MySQL库存,必然导致超卖。
准备Redis库存键
启动服务前,将商品库存同步进Redis:SET sku:2001:stock 100。这一步必须完成,【否则后续所有DECR操作都基于不存在的key,返回null导致逻辑误判】。
使用字符串类型存储单商品库存,不推荐用Hash结构做此用途——除非你需要同时维护已售、冻结等多状态字段。
PHP中调用原子DECR扣减
用户发起抢购请求后,执行以下代码:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$left = $redis->decr('sku:2001:stock');
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
DECR命令本身是原子的,无需额外加锁或事务包裹。它会立即读取当前值、减1、写回,三步不可分割。
注意:若库存原为0,DECR后返回-1,这就是超卖信号——你必须立刻拦截该结果并拒绝下单,不能继续走创建订单流程。
判断扣减结果并响应用户
第一步:检查返回值是否大于等于0。
第二步:若 $left >= 0,说明扣减成功,可进入订单生成环节;若 $left
第三步:还原操作必须用 INCR 命令,且仅在 $left if ($left incr('sku:2001:stock'); echo '库存不足'; }
这一步不能省略。因为DECR已把库存变成负数,不及时加回来,后续所有请求都会拿到错误的负值,导致整个秒杀活动失效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










