MySQL中如何加排他锁:使用SELECT ... FOR UPDATE语句

在MySQL中,加排他锁主要通过SELECT ... FOR UPDATE语句实现,它会在事务中对查询到的数据行加上排他锁,阻止其他事务对这些行进行读取(使用FOR UPDATE或LOCK IN SHARE MODE)或修改,直到当前事务提交或回滚,排他锁是保证数据一致性和避免并发冲突的关键机制,尤其适用于需要先读取后更新的场景,如库存扣减、账户余额变更等。

mysql 如何加 排他锁,MySQL如何添加排他锁详解

排他锁的基本用法

在事务中执行以下SQL语句即可加排他锁:

START TRANSACTION;
SELECT * FROM table_name WHERE condition FOR UPDATE;
-- 执行数据更新操作
UPDATE table_name SET column = value WHERE condition;
COMMIT;
  • FOR UPDATE:对查询结果集中的每一行加排他锁。
  • 事务必要:排他锁必须在事务中生效,提交或回滚后自动释放。
  • 锁定范围:根据WHERE条件锁定匹配的行;若条件未命中索引,可能升级为表级锁,影响性能。

适用场景与注意事项

  1. 典型场景

    • 财务交易:确保账户余额查询与扣款操作的原子性。
    • 库存管理:防止超卖,例如电商秒杀活动。
    • 订单处理:避免同一订单被重复修改。
  2. 注意事项

    • 死锁风险:多个事务互相等待锁释放可能导致死锁,需通过超时机制(如innodb_lock_wait_timeout)或重试策略处理。
    • 索引优化:务必为WHERE条件字段建立索引,避免全表扫描引发表锁。
    • 隔离级别:排他锁在可重复读(REPEATABLE READ)读已提交(READ COMMITTED) 隔离级别下生效,但行为略有差异(如间隙锁的范围)。

与共享锁的区别

  • 共享锁(SELECT ... LOCK IN SHARE MODE):允许多事务并发读取,但禁止修改。
  • 排他锁(SELECT ... FOR UPDATE):禁止其他事务读取(使用锁)或修改,独占性更强。

实战示例

假设有商品库存表products,扣减库存时加排他锁:

START TRANSACTION;
SELECT stock FROM products WHERE id = 100 FOR UPDATE;
-- 检查库存充足后更新
UPDATE products SET stock = stock - 1 WHERE id = 100;
COMMIT;

此操作确保在并发环境下,id为100的商品库存不会被重复扣减。

性能与锁监控

  • 监控锁等待:使用SHOW ENGINE INNODB STATUS查看锁信息。
  • 优化建议:尽量缩小锁定范围(如精确索引条件),并减少事务持有锁的时间。

在MySQL中,SELECT ... FOR UPDATE是实现排他锁的标准方式,结合事务控制可有效保障数据操作的独占性,正确使用时需注意索引设计、死锁防范及隔离级别配置,以平衡数据安全与系统并发性能,对于高并发场景,建议结合乐观锁(版本号机制)或队列处理进一步优化。

未经允许不得转载! 作者:HTML前端知识网,转载或复制请以超链接形式并注明出处HTML前端知识网

原文地址:https://www.html4.cn/13976.html发布于:2026-08-31