提问人:Ecuador 提问时间:11/10/2023 最后编辑:Ecuador 更新时间:11/10/2023 访问量:28
MySQL UPDATE / DELETE 死锁使用模
MySQL UPDATE / DELETE deadlock using modulo
问:
我有一个表,其中有一列,它是一个整数索引。有许多进程必须选择不冲突的用户并进行一些处理。我为此使用模数,所以在某些时候,他们会这样做(例如,在 4 个线程的情况下):user_id
UPDATE table SET data = x WHERE user_id % 4 = y;
其中 y 为 0 到 3,用于标记哪个特定线程正在工作。不幸的是,MySQL不能像这样使用user_id索引,所以它似乎锁定了所有表来扫描它。如果它只有一个 READ 锁,这会导致死锁,而另一个进程正在执行如下操作:
DELETE FROM table WHERE user_id = z;
您认为解决这个问题的最佳方法是什么?
我想我可以有一个单独的查询,得到结果(这将是几百个),然后用一个来代替。
我不确定锁如何用于嵌套选择,所以也许可以:SELECT user_id FROM table WHERE user_id % 4 = y
user_id IN (...)
UPDATE table SET data = x WHERE user_id IN (SELECT user_id from table WHERE user_id % 4 = y)
也工作,以避免获取 SELECT 结果来执行 UPDATE?
否则我想我可以使用 LOCK TABLES 等,但我认为这不太好,所以我很好奇是否还有其他需要考虑的事情。
答:
0赞
Barmar
11/10/2023
#1
创建一个包含所需 ID 的临时表。然后你可以加入它,它应该只锁定这些行。
CREATE TEMPORARY TABLE temp_ids AS
SELECT id
FROM table
WHERE id % 4 = @y;
UPDATE table AS t
JOIN temp_ids as i ON t.id = i.id
SET t.data = @x;
如果您使用子查询或 CTE 联接,我认为它不会起作用,因为我怀疑这会在组合查询期间保持表锁定。
评论
0赞
Ecuador
11/10/2023
是的,我不认为可以通过单个查询来完成。我想我会选择一张临时桌子,它相当“干净”,而且似乎表现良好。
评论