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

排他锁的基本用法
在事务中执行以下SQL语句即可加排他锁:
START TRANSACTION; SELECT * FROM table_name WHERE condition FOR UPDATE; -- 执行数据更新操作 UPDATE table_name SET column = value WHERE condition; COMMIT;
- FOR UPDATE:对查询结果集中的每一行加排他锁。
- 事务必要:排他锁必须在事务中生效,提交或回滚后自动释放。
- 锁定范围:根据WHERE条件锁定匹配的行;若条件未命中索引,可能升级为表级锁,影响性能。
适用场景与注意事项
-
典型场景:
- 财务交易:确保账户余额查询与扣款操作的原子性。
- 库存管理:防止超卖,例如电商秒杀活动。
- 订单处理:避免同一订单被重复修改。
-
注意事项:
- 死锁风险:多个事务互相等待锁释放可能导致死锁,需通过超时机制(如
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





