You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FOR UPDATE行锁是否会延伸到关联JOIN查询涉及的表?

前提说明

以下结论基于支持行级锁的事务型数据库(如MySQL InnoDB、PostgreSQL)推导,已知books表存在指向authors表的外键author_id,涉及两个查询如下:
第一个查询(对books表对应行加排他行锁):

SELECT * FROM books
WHERE books.author_id = 1
FOR UPDATE

第二个查询(关联查询authors和books表):

SELECT * FROM authors
JOIN books ON books.author_id = authors.id
WHERE authors.id = 1

注:阻塞的前提是第一个查询所在的事务未提交/回滚,排他锁还处于持有状态,如果第一个查询执行完就立刻提交事务,锁会自动释放,不会出现后续阻塞问题。


第一个查询是否会阻塞第二个查询?

要分场景判断:

  • 默认场景(数据库隔离级别为读提交/可重复读,第二个查询为普通无锁SELECT):不会阻塞。普通SELECT默认走快照读,读取的是数据的历史版本,不会尝试获取books表对应行上的排他锁,因此不需要等待第一个事务释放锁,直接就能返回结果。
  • 特殊场景(第二个查询加锁/隔离级别为串行化):会阻塞。如果第二个查询手动加了FOR UPDATE/FOR SHARE,或者数据库隔离级别调整为SERIALIZABLE,此时第二个查询访问books表中author_id=1的行时,需要申请对应的共享/排他锁,和第一个查询持有的排他锁冲突,必须等第一个事务提交或回滚释放锁之后才能继续执行。

加的锁是否会延伸到所有带JOIN的books查询?

不会。
首先这个排他锁只加在books表中author_id=1的行上,既不会关联到authors表的记录,也不会覆盖books表的其他行。其次锁只会对需要访问被加锁行、并且需要申请行锁的操作生效,如果JOIN查询走快照读,或者访问的是books表其他行,完全不会受这个锁的影响。
举个例子:如果把第二个查询的条件改成WHERE authors.id = 2,整个查询不会触碰到author_id=1的books行,根本不会和第一个查询的锁产生任何冲突。


内容的提问来源于stack exchange,提问作者ar.thewaterfall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 19:36:07