面试官:select......for update会锁表还是锁行?

面试官:select......for update会锁表还是锁行?
最新回答
西雅图很忙°

2026-10-24 15:31:36

select...for update是悲观锁的一种实现,其加锁范围取决于查询条件是否使用索引/主键:

  • 使用索引/主键:锁定符合条件的行记录(行锁)
  • 未使用索引/主键:锁定整张表(表锁)
验证过程分析1. 主键索引验证
  • 操作:通过主键id=1查询并加锁,另一个事务尝试更新id=2的记录。

  • 结果:更新成功(未被阻塞),说明仅锁定了id=1的行。

2. 唯一索引验证
  • 操作:通过唯一索引age=18查询并加锁,另一个事务尝试更新age=20的记录。

  • 结果:更新成功(未被阻塞),说明仅锁定了age=18的行。

3. 无索引字段验证
  • 操作:通过无索引字段code='A'查询并加锁,另一个事务尝试更新其他记录。

  • 结果:更新被阻塞,说明锁定了整张表。

关键结论
  1. 行锁条件:查询条件必须命中索引(主键或唯一索引),否则会退化为表锁。
  2. 表锁风险:未使用索引时,锁的粒度扩大到整张表,导致并发性能下降。
  3. 手动提交控制:需通过set autocommit=0关闭自动提交,确保锁在事务结束前生效。
实际应用建议
  • 优先使用索引字段:确保for update锁定最小范围。
  • 避免全表扫描:无索引的for update可能导致锁冲突,影响系统并发能力。
  • 监控锁等待:通过show processlist或information_schema排查锁阻塞问题。

通过以上验证和结论,可以明确select...for update的锁行为与索引的强关联性,合理设计查询条件是优化锁粒度的关键。