MySQL悲观锁和乐观锁的实现方案详解(附面试应答技巧)
在数据库面试中,“悲观锁和乐观锁怎么实现”几乎是必考题。作为开发者,理解这两种并发控制机制的实际落地方式至关重要。下面从面试实战角度拆解实现方案:
🔒 一、什么是悲观锁?怎么实现?
核心思想:假定一定会发生冲突,操作前先锁住数据。
MySQL实现方案:
SELECT ... FOR UPDATE
在事务中查询时直接锁定记录,其他事务无法修改(共享锁可读):START TRANSACTION; SELECT * FROM orders WHERE id = 100 FOR UPDATE; -- 锁定该行 UPDATE orders SET amount = amount - 50 WHERE id = 100; COMMIT;- 行级锁依赖:
- 需要InnoDB引擎
- WHERE条件必须命中索引(否则锁表)
- 事务提交后自动释放锁
适用场景:高冲突场景(如余额扣减)
🔄 二、什么是乐观锁?怎么实现?
核心思想:假定不会冲突,提交时检测版本变化。
MySQL实现方案:
-
版本号控制(主流方案)
UPDATE products SET stock = stock - 1, version = version + 1 WHERE id = 200 AND version = 5; -- 提交时校验版本- 若返回影响行数=0,说明版本过期需重试
-
时间戳控制
原理同版本号,用timestamp字段替代版本号校验
适用场景:低冲突场景(如商品浏览数更新)
⚖️ 三、两种锁的对比场景
| 维度 | 悲观锁 | 乐观锁 | |------------|-------------------------|----------------------| | 冲突处理 | 事前预防 | 事后检测 | | 性能开销 | 锁管理成本高 | 无锁,重试消耗低 | | 数据竞争 | 高并发下易阻塞 | 并发吞吐量更高 | | 实现复杂度 | 数据库原生支持 | 需业务逻辑配合 |
📌 面试应答技巧:
被问到选择依据时,结合业务场景回答:
“如果是秒杀库存扣减这种强竞争场景,我会用悲观锁确保数据安全;
如果是更新文章点赞数这种低频操作,用乐观锁减少数据库压力。”
💡 四、高频面试题延伸
-
乐观锁ABA问题怎么解决?
→ 答:追加递增版本号(MySQL方案天然规避此问题) -
FOR UPDATE会锁表吗?
→ 答:WHERE命中索引锁行,未命中索引锁表(必考!) -
乐观锁失败后怎么处理?
→ 答:前端提示+后端重试机制(建议重试3次)
📚 推荐学习:2025年最新Java面试题库(含MySQL深度解析)
链接:https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码:9b3g
需要开通面试鸭会员的同学注意啦!通过👉 面试鸭返利网 👈联系我可返25元,海量大厂真题+实时更新助你轻松通关:

(点击图片进入官网领取返利)


