【锁表】面试高频考点深度解析:程序员必懂的数据库并发控制
💡 面试官为啥总爱问"锁表"?
每次面试问到数据库事务,十有八九会蹦出“锁表”相关的问题。去年面蚂蚁时,面试官直接甩了个场景:“双十一库存超卖怎么防?”——核心就是锁表机制啊兄弟们!锁表作为数据库并发控制的基石,本质是解决多个事务同时操作数据时的资源冲突问题。

🔒 锁表到底锁住了什么?
简单说就是锁住数据访问权限。比如你update某行数据时:
- 数据库会先给这行加行级锁(比如X锁)
- 其他事务想修改这行就会被阻塞
- 直到你commit后锁才释放
这就像厕所隔间门锁——里面有人(锁表),外面的人(其他事务)只能等着(阻塞)。但锁表不当就会引发经典问题:
⚠️ 死锁:锁表最让人头疼的坑
上周团队就遇到个生产事故:
-- 事务1
UPDATE orders SET status=1 WHERE id=100; -- 锁住订单100
UPDATE users SET credit=credit-100 WHERE id=200; -- 尝试锁用户200
-- 事务2(同时运行)
UPDATE users SET credit=credit+100 WHERE id=200; -- 锁住用户200
UPDATE orders SET status=2 WHERE id=100; -- 尝试锁订单100
结果就是互相锁表!事务1锁着订单等用户,事务2锁着用户等订单——典型的死锁现场。
🛠️ 实战避坑指南(面试加分点)
被问到“如何避免死锁”时,可以这样答:
-
锁顺序法则
所有事务按相同顺序加锁(比如先锁用户表再锁订单表) -
锁超时设置
SET innodb_lock_wait_timeout=3;超过3秒自动放弃 -
尽量用行锁
避免LOCK TABLES ... WRITE这种表级锁 -
即查即更原则
-- 反例 SELECT balance FROM account WHERE id=1; -- 先查 UPDATE account SET balance=200 WHERE id=1; -- 后改(可能被其他事务修改) -- 正解 UPDATE account SET balance=balance-100 WHERE id=1; -- 原子操作
💎 高频面试题精讲
Q:悲观锁和乐观锁怎么选?
👉 悲观锁(如SELECT ... FOR UPDATE):适合写多读少场景(比如秒杀)
👉 乐观锁(加version字段):适合读多写少场景(比如文章更新)
Q:间隙锁(Gap Lock)是什么鬼?
当执行SELECT * FROM table WHERE id BETWEEN 10 AND 20 FOR UPDATE时,不仅锁住10-20的现有数据,连这个区间内的空白位置也一起锁表!防止其他事务插入新数据。

📌 附:2025年Java面试宝典最新版
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g
🚀 小福利
如果需要开通面试鸭会员,通过👉 面试鸭返利网 👈找我下单可返现25元!实测比官方直接买便宜:
锁表问题本质是资源争夺战,理解InnoDB的锁表机制(记录锁、间隙锁、临键锁)能让你在面试中碾压90%的候选人。建议把文中的案例自己用MySQL跑一遍,比死记概念管用十倍!



