mysql - 带有范围谓词的 UPDATE 语句是否会“优先”非锁定行
问题描述
给定一个名为的表workers
和一个带有列的模式leaderId
,lastUpdated
. 当多个数据库连接运行该语句时,是否会优先考虑更新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
解决方案
简短的回答:没有。
长答案:
全部或没有。这是 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
。所以,请解释您的代码。我可能有其他提示。)
推荐阅读
- c - 代码块问题
- security - JPQL 注入和 SQL 注入之间有什么区别
- java - 如何在 neo4j 嵌入式应用程序中注册“apoc.algo.dijkstra”?
- neo4j - Neo4J - 获取没有重复关系类型或节点标签的所有路径
- php - 警告:模块 mcrypt ini 文件不存在,但已安装
- ajax - 无法将 JSON 数据从 Django 发送到 javascript
- c++ - 为什么我的析构函数被多次调用?
- javascript - 我的一些条件被忽视了
- django - 更改 django 模板中的字符串?
- python - 在 NumPy 和 GSL 之间共享随机生成器状态