分布式锁实现幂等:面试高频考点解析

2025年Java面试宝典抢先下载:
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g
一、什么是幂等性?为什么需要分布式锁?
想象一个支付场景:用户点了两次付款按钮。如果系统没做幂等,可能扣两次钱——这就是事故!幂等性的核心是:无论操作执行多少次,结果都保持一致。而分布式锁是实现它的黄金搭档,尤其在集群环境下防止并发重复操作。
二、分布式锁实现幂等的三大核心方案
方案1:数据库唯一索引
- 实现逻辑
给业务表加唯一索引(比如订单号+状态)。当重复请求插入相同数据时,数据库直接报错。 - 适用场景
创建类操作(如生成订单),简单粗暴有效! - 致命缺陷
无法覆盖更新类操作(比如扣减库存),且高并发下数据库压力大。
方案2:Redis分布式锁(最常用!)
graph LR
A[请求携带唯一ID] --> B{Redis setnx锁是否存在}
B -- 不存在 --> C[加锁执行业务]
B -- 存在 --> D[拒绝请求]
C --> E[释放锁]
- 关键细节
- 锁的Key=业务ID(如订单号),Value=随机值(防误删)
- 必须设置过期时间!避免死锁
- 解锁时用Lua脚本保证原子性:
if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1])
- 面试坑点
- 单节点Redis锁有脑裂风险(Redlock可解)
- 锁过期时间设置太短会导致业务未完成锁已释放
方案3:ZooKeeper临时有序节点
- 实现逻辑
- 每个请求在ZK创建临时有序节点
- 判断自己是否是最小节点→是则获得锁
- 业务完成删除节点
- 优势
通过Watch机制实现阻塞等待,无过期时间烦恼 - 劣势
ZK性能低于Redis,需维护长连接

三、生产环境避坑指南
- 锁范围要精准
错误示例:把整个支付方法加锁→性能暴跌
正确做法:锁粒度细化到用户ID或订单号 - 重试机制必须有限次
避免死循环!建议3次重试后返回错误 - 超时时间动态计算
根据历史监控数据调整,比如设置:平均耗时*2 + 缓冲时间
四、分布式锁的实际应用
当你在面试鸭返利网开通会员时,背后的支付系统正是用Redis分布式锁保证:即使你手抖点了两次支付,也只会扣一次钱。如果你需要购买面试鸭会员,通过面试鸭返利网找我可返利25元!
五、面试这样答能加分
“我们项目用Redis+Lua实现分布式锁做幂等。具体步骤:
- 前端提交时生成唯一请求ID
- 用SET key_id NX EX 30抢锁
- 抢到锁查流水表判断是否重复
- 执行业务后删除锁(Lua校验Owner)
关键优化点:
- 锁过期时间根据业务监控动态调整
- 采用Redisson框架避免轮询浪费资源
- 对锁失败请求做补偿队列异步重试”

最后叮嘱:分布式锁不是银弹!对于极致性能场景,可考虑状态机幂等或Token机制。但面试中能把分布式锁讲清楚,足够让面试官眼前一亮了。
更多面试真题解析 → 面试鸭返利网
(悄悄说:通过本站购买面试鸭会员,找我返现25元红包!)


