← 返回并发与锁

⚡ 超卖问题

100件商品卖了110件 —— 秒杀经典问题

📊 超卖发生过程
stock=1 线程A 读 stock=1,>0 通过 线程B 读 stock=1,>0 通过 stock=0 stock=-1 ❌超卖 下单成功 下单成功(超卖!)

❌ 错误:查+减非原子

int s = dao.getStock(id); if (s > 0) { dao.decrStock(id); order.create(); }

✅ 正确:原子扣减

// DB条件更新 int n = dao.decrIfPositive(id); // UPDATE SET stock=stock-1 // WHERE id=? AND stock>0 if (n==0) throw "售罄"; // 或 Redis 原子 long left = redis.decr(key); if (left<0){redis.incr(key);throw"售罄";}
🏗️ 秒杀系统架构(请求层层削减)
10万用户 CDN+验证码(挡80%) Nginx限流(挡15%) Redis预减(只放100) MQ异步下单 DB下单
秒杀三板斧:限流(CDN+验证码+Nginx+Sentinel,层层削减);② 缓存(Redis预减库存,原子操作,不碰DB);③ 异步(MQ削峰,抢到=发消息,消费者慢慢下单)。核心:让尽量少的请求碰到数据库。
并发与锁 · 超卖问题 · 全栈资料库