行级锁通过锁定特定行而非整表提升并发性能,InnoDB利用索引项实现行级锁,使用SELECT ... FOR UPDATE加排他锁、LOCK IN SHARE MODE加共享锁,需确保WHERE条件走索引、缩短事务时间、避免死锁,并合理设置隔离级别以优化并发控制。

MySQL中的行级锁主要用于提高并发性能,尤其是在InnoDB存储引擎中。它允许事务锁定表中的特定行,而不是整个表,这样其他事务可以同时操作表中不同的行,从而提升并发处理能力。
行级锁的基本概念
行级锁是在事务执行过程中自动加锁的机制,常见于UPDATE、DELETE和SELECT ... FOR UPDATE等语句中。InnoDB通过索引项加锁来实现行级锁,因此使用索引是触发行级锁的关键。
如果没有合适的索引,InnoDB可能会升级为表锁,导致并发下降。
如何使用SELECT ... FOR UPDATE加行锁
在事务中使用SELECT ... FOR UPDATE可以显式地对查询到的行加排他锁(X锁),防止其他事务修改或加锁这些行。
示例:
START TRANSACTION; SELECT * FROM users WHERE id = 1 FOR UPDATE; -- 此时id=1的行被当前事务锁定 UPDATE users SET balance = balance - 100 WHERE id = 1; COMMIT;
在这个例子中,从SELECT ... FOR UPDATE开始,直到事务提交,其他事务无法修改id为1的记录,也无法对其执行SELECT ... FOR UPDATE或LOCK IN SHARE MODE。
使用LOCK IN SHARE MODE加共享锁
如果只是想防止其他事务修改某行,但允许读取,可以使用LOCK IN SHARE MODE,它会加上共享锁(S锁)。
示例:
START TRANSACTION; SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE; -- 其他事务可以读,但不能修改该行 UPDATE users SET name = 'Tom' WHERE id = 1; -- 当前事务可修改 COMMIT;
多个事务可以同时持有同一行的共享锁,但只要有共享锁存在,任何事务都不能获得排他锁。
注意事项与最佳实践
- 确保WHERE条件走索引:否则InnoDB可能扫描全表并锁定大量不必要的行,甚至退化为表锁。
- 尽量缩短事务时间:长时间持有行锁会导致其他事务阻塞,影响系统吞吐量。
- 注意死锁风险:多个事务以不同顺序访问多行数据时容易产生死锁,InnoDB会自动检测并回滚其中一个事务。
- 合理使用隔离级别:在REPEATABLE READ级别下,InnoDB使用间隙锁(Next-Key Locking)防止幻读,这也属于行级锁的扩展。
基本上就这些。只要用好索引、控制事务范围、理解锁类型,MySQL的行级锁就能有效支持高并发场景。










