秒杀系统怎样防止超卖?
先自己想一想,再看参考要点
参考要点
- 超卖源于判断库存和扣减库存不是原子操作
- 数据库中可用悲观锁 SELECT ... FOR UPDATE、乐观锁版本号或条件更新 UPDATE ... SET stock = stock - 1 WHERE stock > 0
- 实测 1000 个用户抢 100 件,先查再扣多卖了 34~62 件,悲观锁和条件更新都恰好卖出 100 件
- 乐观锁不会超卖,但冲突多时会少卖,150 个用户抢、重试 3 次也只卖出 48~57 件
- 条件更新不需要重试、最常用
- 秒杀时先用 Redis 的 Lua 脚本挡住大部分请求,数据库的条件更新作为最后一道防线