《面试官:说说电商库存扣减如何防超卖?分布式锁的三种实现》

简介: 这是一道电商高频面试题,聚焦库存防超卖与分布式锁实战。提供可直接背诵的“三段式”方案(Redis Lua预扣 + MQ异步 + DB乐观锁),详解Redis/ZK/DB三种锁原理、源码级实现、避坑指南及大厂选型逻辑,兼顾技术深度与落地能力。(239字)

这是一个经典的电商高频面试题,也是很多同学容易“背概念、缺落地”的地方。下面我给你一套面试可直接背诵 + 技术深度拉满的回答模板,同时补齐源码级原理和避坑指南。

🛒 面试官:说说电商库存扣减如何防超卖?分布式锁的三种实现

面试核心思路:先说业务模型 → 再说并发问题 → 给出三种锁方案 → 对比选型 → 兜底方案

一、先给结论(一句话版)

防超卖的本质:保证库存扣减的“原子性 + 幂等性”。

实践中通常采用:

Redis 原子扣减(Lua) + 数据库乐观锁 + 分布式锁兜底。

二、超卖是怎么发生的?(面试官爱问)

典型并发场景

库存 = 1
线程A:查库存 = 1 ✅
线程B:查库存 = 1 ✅
线程A:扣减库存 → 0 ✅
线程B:扣减库存 → -1 ❌(超卖)

根本原因

问题 说明

非原子操作 select → judge → update 被拆分

并发竞争 多线程同时进入临界区

重试机制 MQ 重试导致重复扣减

三、正确的库存扣减模型(重点)

✅ 强烈推荐的“三段式”模型

1️⃣ Redis 预扣(高性能、抗并发)
2️⃣ MQ 异步落库(解耦、削峰)
3️⃣ DB 最终扣减(强一致)

核心原则

✅ 不要直接在高并发下操作 MySQL
✅ 所有写库存必须是原子操作
✅ 任何扣减都必须幂等

四、分布式锁的三种实现(面试正菜)

✅ 方案一:Redis 分布式锁(最常用)

1️⃣ 加锁(SET NX PX)

SET lock:stock:1001 uuid NX PX 30000

2️⃣ 解锁(Lua 保证原子性)

if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
end

3️⃣ Java 示例(简化版)

String uuid = UUID.randomUUID().toString();
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent("lock:stock:1001", uuid, 30, TimeUnit.SECONDS);

if (locked) {
try {
deductStock(); // 核心业务
} finally {
unlock(uuid);
}
}

✅ 优点

• 性能极高(内存级)

• 实现简单

• 适合秒杀、高并发

❌ 缺点

• 主从切换可能丢锁(CAP)

• 锁过期 ≠ 业务执行完成

✅ 解决方案

• Redisson Watch Dog(自动续期)

• RedLock(多实例)

✅ 方案二:ZooKeeper 分布式锁(最稳)

原理

/lock
├── /order-000001(临时顺序节点)
├── /order-000002
└── /order-000003

• 谁序号最小,谁拿到锁

• 客户端断连 → 节点自动删除 → 锁释放

Curator 示例

InterProcessMutex lock =
new InterProcessMutex(client, "/lock/stock");

lock.acquire();
try {
deductStock();
} finally {
lock.release();
}

✅ 优点

• CP 强一致

• 不会误删锁

• 天然防死锁

❌ 缺点

• 性能不如 Redis

• 运维复杂

✅ 使用场景

• 资金类

• 订单创建

• 核心配置变更

✅ 方案三:数据库锁(最朴素但有效)

方式 1️⃣:悲观锁(不推荐)

SELECT * FROM stock WHERE id=1 FOR UPDATE;

❌ 缺点:
• 连接被长时间占用

• 极易拖垮数据库

✅ 方式 2️⃣:乐观锁(强烈推荐)

UPDATE stock
SET quantity = quantity - 1,
version = version + 1
WHERE id = 1
AND quantity >= 1
AND version = old_version;

Java 判定

if (rows == 0) {
throw new RuntimeException("库存扣减失败");
}

✅ 优点

• 无锁、高并发

• 天然防超卖

• 数据库兜底方案

❌ 缺点

• 重试成本高

• 不适合秒杀级流量

五、三种分布式锁对比(面试必背)

维度 Redis ZooKeeper 数据库

性能 ⭐⭐⭐⭐ ⭐⭐ ⭐

一致性 AP CP CP

实现难度 中 高 低

死锁风险 有 无 无

典型场景 秒杀、缓存 核心业务 低频扣减

六、真正的大厂方案(加分项)

✅ Redis Lua 原子扣减(无锁胜有锁)

local stock = tonumber(redis.call("get", KEYS[1]))
if stock >= tonumber(ARGV[1]) then
return redis.call("decrby", KEYS[1], ARGV[1])
else
return -1
end

👉 面试金句:

“在高并发库存扣减场景中,我们优先使用 Redis Lua 原子操作,只有在复杂业务或幂等控制时才引入分布式锁。”

七、完整面试标准答案(可直接背)

面试官:说说电商库存扣减如何防超卖?

✅ 标准回答模板:

防超卖的核心是原子性 + 幂等性。

我们一般分三层来做:

第一层,在 Redis 中用 Lua 脚本做原子扣减,保证高并发下不超卖;

第二层,通过 MQ 异步将扣减请求发到下游,由消费者用数据库乐观锁完成最终扣减;

第三层,为了防止极端并发和重复请求,我们会使用 分布式锁。

分布式锁我们有三种实现:

1️⃣ Redis 锁:性能好,适合秒杀,但要注意锁续期和主从切换问题;

2️⃣ ZooKeeper 锁:强一致,适合资金、订单等核心业务;

3️⃣ 数据库乐观锁:通过 version 或 CAS 更新,作为最终兜底。

在实际生产中,我们更倾向 Redis + Lua + 乐观锁 的组合方案。

八、面试官追问准备

Q:Redis 锁过期了,业务还没执行完怎么办?

✅ 答:Redisson 的 Watch Dog 自动续期。

Q:Redis 主从切换锁丢了怎么办?

✅ 答:使用 RedLock 或多实例仲裁。

Q:MQ 重复消费会不会超卖?

✅ 答:订单号 / 流水号 幂等校验。

九、总结一句话

防超卖不是靠一把锁,而是靠“原子操作 + 幂等设计 + 分层兜底”。
以上是我在电商中台领域的一些实践,目前我正在这个方向进行更深入的探索/提供相关咨询与解决方案。如果你的团队有类似的技术挑战或合作需求,欢迎通过[我的GitHub/个人网站/邮箱]与我联系
你想继续哪一个?

相关文章
|
5天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
10798 69
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
5天前
|
人工智能 IDE API
2026年国内 Codex 安装教程和使用教程:GPT-5.4 完整指南
Codex已进化为AI编程智能体,不仅能补全代码,更能理解项目、自动重构、执行任务。本文详解国内安装、GPT-5.4接入、cc-switch中转配置及实战开发流程,助你从零掌握“描述需求→AI实现”的新一代工程范式。(239字)
3426 129
|
1天前
|
人工智能 Kubernetes 供应链
深度解析:LiteLLM 供应链投毒事件——TeamPCP 三阶段后门全链路分析
阿里云云安全中心和云防火墙已在第一时间上线相关检测与拦截策略!
1247 5
|
2天前
|
人工智能 自然语言处理 供应链
【最新】阿里云ClawHub Skill扫描:3万个AI Agent技能中的安全度量
阿里云扫描3万+AI Skill,发现AI检测引擎可识别80%+威胁,远高于传统引擎。
1219 1
|
11天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
2608 6