2

我们有一个使用 MySQL 的 InnoDB 行级锁定的高性能 Django Web 应用程序。在我们的代码中,我们看到(在进程 A 中)表中的特定行是否可以通过使用SELECT … FOR UPDATE. 如果有另一个进程 (B) 正在使用该行,并且首先到达那里,那么该行上将有一个排他锁,并且 A 将获得一个“锁定等待超时”异常。A 会抓住这一点,然后继续尝试另一行(使用类似的SELECT … FOR UPDATE方法)。

但是,我不能 100% 确定锁定等待超时发生时会发生什么。在 B 完成并释放它的锁之后,即使 A 的“select ... for update”查询已超时,并且 A 已继续锁定另一行,是否会为 A 提供排他锁?

或者(这就是我认为直觉上会发生的事情),在 A 尝试获得锁失败之后,它继续前进,B 提交并完成:是否没有进一步尝试将锁给 A?

最好是官方 MySQL 文档中的任何参考/引用,因为它是规范的来源。我在文档中找不到任何专门解决当您尝试获得锁并且超时时会发生什么的内容。

4

1 回答 1

3

永远不会获取超时语句请求的锁:

当发生锁定等待超时时,当前语句将回滚。

下面的测试证明了这个事实:

-- "atable" is an InnoDB table

-- Connection #1
BEGIN;
UPDATE atable SET acol = 1 WHERE acol = 2;

-- Connection #2
BEGIN;
SELECT * FROM atable FOR UPDATE; -- hangs

-- Connection #3
BEGIN;
SELECT * FROM atable FOR UPDATE; -- hangs

-- wait until Connection #2 times out
-- Connection #2
-- "Lock wait timeout exceeded"

-- Connection #1
COMMIT;

-- Connection #3 resumes execution and data is displayed
于 2013-05-15T13:58:08.593 回答