首页 > 解决方案 > 带有范围谓词的 UPDATE 语句是否会“优先”非锁定行

问题描述

给定一个名为的表workers和一个带有列的模式leaderIdlastUpdated. 当多个数据库连接运行该语句时,是否会优先考虑更新UPDATE满足谓词(子句)的非锁定行,还是将查询阻塞在锁定的匹配行上?如果不先考虑解锁,有没有办法做到这一点?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

标签: mysqlsql-updatemysql-5.7

解决方案


简短的回答:没有。

长答案:

全部或没有。这是 InnoDB“事务”的首要任务。您的BEGIN...COMMIT控制交易的范围。

DATE_SUB(NOW(6),INTERVAL 3 SECOND)并将在语句NOW(6)的开头计算一次。UPDATE

你有LIMIT 1没有ORDER BY. 这意味着您无法预测将选择哪 1 行。但是,优化器不会根据执行查询的速度以外的任何因素来选择行,而不考虑可能被锁定的内容

看起来您正在实施“队列”?“UPDATE抓取”一行,然后SELECT获取该行中的数据?

OR优化不佳。一般来说,没有索引是有用的,因此UPDATE它将以某种方便的顺序扫描整个表,当它发现满足一个或另一个条件时停止。

通常的优化OR是将其分成两个查询。这可能意味着更改您的整体逻辑以使主代码获取NULL. 并且有一个单独的“收割者”进程,它围绕着抓取任何“旧”项目(可能是由于工人崩溃而成为孤儿)。

(我犹豫是否建议重写,因为我不完全理解您的逻辑。我希望对表格queue采取行动,而不是workers。所以,请解释您的代码。我可能有其他提示。)


推荐阅读