首页 >文档 > MySQL乐观锁mysql 乐观锁和悲观锁的实现

MySQL乐观锁mysql 乐观锁和悲观锁的实现

MySQL乐观锁与悲观锁是数据库并发控制的核心技术。本文详细解析两种锁的实现原理:悲观锁通过SELECT FOR UPDATE直接锁定记录,适合高并发写场景;乐观锁通过版本号/时间戳检测冲突,提升读多写少场景的性能。文章对比了适用场景,给出实战案例(如库存扣减),并分享面试回答技巧。包含SQL示例、性能对比和选择建议,帮助开发者深入理解MySQL锁机制,解决数据一致性问题。附2025Java面试宝典资源,助力技术提升。

MySQL乐观锁与悲观锁的实现详解

作为程序员,数据库锁机制是面试必考题。今天我们来聊聊MySQL乐观锁悲观锁的实现原理,帮你轻松应对技术面!

面试鸭返利网
(🔎 锁机制是面试高频考点)

📘 2025Java面试宝典
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g


🔐 悲观锁:先下手为强

悲观锁的核心思想是“数据一定会被修改”,所以在操作前直接加锁。MySQL中主要通过以下两种方式实现:

  1. SELECT ... FOR UPDATE
    在事务中查询时直接锁定记录,其他事务无法修改或加锁:

    START TRANSACTION;
    SELECT * FROM orders WHERE id=1 FOR UPDATE; -- 锁定该行
    UPDATE orders SET amount=100 WHERE id=1;
    COMMIT;
    
  2. SELECT ... LOCK IN SHARE MODE
    共享锁允许多个事务读同一数据,但禁止任何事务修改:

    SELECT * FROM products WHERE stock>0 LOCK IN SHARE MODE;
    

💡 适用场景:高并发写操作(如秒杀库存修改)


🚀 乐观锁:事后冲突检测

MySQL乐观锁不主动加锁,而是通过版本号/时间戳检测冲突,典型实现方式:

  1. 版本号控制(最常用)

    UPDATE users 
    SET balance = balance-100, version = version+1 
    WHERE id=1 AND version=3; -- 检测版本是否变化
    
  2. 时间戳比对

    UPDATE products 
    SET stock=stock-1, update_time=NOW() 
    WHERE id=10 AND update_time='2023-01-01 12:00:00';
    

优势:减少锁竞争,提升并发性能
注意:需要重试机制处理更新失败


⚖️ 两种锁如何选择?

| 场景 | 推荐方案 | |------------------------|--------------------| | 读多写少(如浏览计数) | ✅ 乐观锁 | | 写操作频繁(如支付) | ✅ 悲观锁 | | 数据冲突概率低 | ✅ 乐观锁 | | 需要强一致性保障 | ✅ 悲观锁 |


💡 面试实战回答技巧

当被问到“如何实现并发扣减库存?”时,可以这样答:

“我们项目采用MySQL乐观锁方案,在商品表添加version字段。每次更新时执行:

UPDATE item 
SET stock = stock-1, version=version+1 
WHERE product_id=1001 AND version=当前版本

如果更新失败就重试3次。相比悲观锁FOR UPDATE,这种方案QPS提升了3倍”


面试鸭返利网
(🛡️ 锁机制保障数据一致性)


需要开通面试鸭会员的同学注意啦!通过 面试鸭返利网 找我购买可返利25元,点击链接了解详情 👇
面试鸭返利优惠

📌 本文永久地址https://mianshiyafanli.com/mysql-optimistic-lock

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

🎯 立即加入面试鸭会员 →

支付宝扫码领取1-8元无门槛红包

支付宝红包二维码