将带有范围谓词 "prefer" 非锁定行的 UPDATE 语句
Will an UPDATE statement with a range predicate "prefer" non-locked rows
给定一个名为 workers
的 table 和一个包含列 leaderId
、lastUpdated
的架构。当多个DB连接是运行这个UPDATE
语句时,是否会考虑update first满足谓词(WHERE
子句)的非锁定行] 还是查询会阻塞在锁定的匹配行上?如果不优先考虑解锁,有没有办法?
BEGIN
UPDATE workers SET leaderId = ?, lastUpdated = NOW(6)
WHERE lastUpdated IS NULL OR lastUpdated < DATE_SUB(NOW(6),INTERVAL 3 SECOND)
LIMIT 1;
SELECT * FROM workers WHERE leaderId = ?;
COMMIT
简答:否
长答案:
全部或none。这是 InnoDB“事务”的主要任务。您的BEGIN
...COMMIT
控制交易的范围。
DATE_SUB(NOW(6),INTERVAL 3 SECOND)
和 NOW(6)
将在 UPDATE
语句的开头计算一次。
您有 LIMIT 1
没有 ORDER BY
。这意味着您无法预测将选择哪 1 行。但是,优化器不会根据执行查询的速度以外的任何其他因素来选择行,而不考虑可能被锁定的内容。
看起来你在实现一个“队列”? UPDATE
'grabs' 一行,然后SELECT
获取那一行的数据?
OR
优化不佳。通常没有索引是有用的,因此 UPDATE
将以某种方便的顺序扫描整个 table,当它发现满足一个或另一个条件时停止。
OR
的通常优化是将其分成两个查询。这可能意味着改变你的整体逻辑让主代码抓取 NULL
。并有一个单独的“收割者”进程,围绕着抓取任何“旧”项目(可能由于工人崩溃而被孤立)。
(我对建议重写犹豫不决,因为我不完全理解你的逻辑。我希望 table queue
被执行,而不是 workers
。所以,请解释你的代码。我可能还有其他提示。)
给定一个名为 workers
的 table 和一个包含列 leaderId
、lastUpdated
的架构。当多个DB连接是运行这个UPDATE
语句时,是否会考虑update first满足谓词(WHERE
子句)的非锁定行] 还是查询会阻塞在锁定的匹配行上?如果不优先考虑解锁,有没有办法?
BEGIN
UPDATE workers SET leaderId = ?, lastUpdated = NOW(6)
WHERE lastUpdated IS NULL OR lastUpdated < DATE_SUB(NOW(6),INTERVAL 3 SECOND)
LIMIT 1;
SELECT * FROM workers WHERE leaderId = ?;
COMMIT
简答:否
长答案:
全部或none。这是 InnoDB“事务”的主要任务。您的BEGIN
...COMMIT
控制交易的范围。
DATE_SUB(NOW(6),INTERVAL 3 SECOND)
和 NOW(6)
将在 UPDATE
语句的开头计算一次。
您有 LIMIT 1
没有 ORDER BY
。这意味着您无法预测将选择哪 1 行。但是,优化器不会根据执行查询的速度以外的任何其他因素来选择行,而不考虑可能被锁定的内容。
看起来你在实现一个“队列”? UPDATE
'grabs' 一行,然后SELECT
获取那一行的数据?
OR
优化不佳。通常没有索引是有用的,因此 UPDATE
将以某种方便的顺序扫描整个 table,当它发现满足一个或另一个条件时停止。
OR
的通常优化是将其分成两个查询。这可能意味着改变你的整体逻辑让主代码抓取 NULL
。并有一个单独的“收割者”进程,围绕着抓取任何“旧”项目(可能由于工人崩溃而被孤立)。
(我对建议重写犹豫不决,因为我不完全理解你的逻辑。我希望 table queue
被执行,而不是 workers
。所以,请解释你的代码。我可能还有其他提示。)