SQL扣减库存需用带条件的UPDATE语句(如WHERE id = ? AND stock >= 1)实现原子检查与扣减,配合主键/唯一索引避免表锁,并通过ROW_COUNT()判断结果;高并发下可叠加Redis预减、分段库存和异步补偿。

SQL交易数据保障的核心原则
交易数据一致性不能只靠应用层控制,必须由数据库提供原子性、隔离性支撑。关键在于利用事务边界明确操作范围,配合行级锁与合理索引,避免脏读、幻读和超卖。
扣减库存时的典型并发问题
多个请求同时读取同一商品库存(如都读到10),各自减1后写回,最终变成9而非8——这就是“丢失更新”。根本原因是读-改-写未构成原子操作,中间存在时间窗口。
推荐的SQL扣减方案(带校验)
用一条带条件的UPDATE语句完成“检查+扣减”,数据库自动加行锁且原子执行:
UPDATE product SET stock = stock - 1 WHERE id = ? AND stock >= 1;
- 执行后检查
ROW_COUNT():为0表示库存不足或已被抢完,业务需捕获并提示“库存不足” - WHERE中的
stock >= 1是安全阀,防止负库存 - 务必确保
id字段有主键或唯一索引,否则可能升级为表锁
高并发下的补充建议
单靠SQL扣减在秒杀等极端场景仍可能压垮数据库。可叠加以下措施:
- 前置缓存校验:Redis中预存库存,扣减前先decr并判断返回值,成功后再走DB落库
- 分段库存:将大库存拆成多个逻辑槽位(如10个slot各100件),分散行锁竞争
- 异步补偿:扣减失败时进入延迟队列重试,配合最终一致性对账
基本上就这些,不复杂但容易忽略WHERE校验和索引约束。










