MySQL 使用模来更新/删除死锁

问题描述 投票:0回答:1

我有一个表,其中有一列

user_id
,它是一个整数索引。有许多进程必须选择不冲突的用户并进行一些处理。我为此使用模数,因此在某些时候,它们会这样做(例如,在 4 个线程的情况下):

UPDATE table SET data = x WHERE user_id % 4 = y;

其中y为0到3,用于标记哪个特定线程正在工作。不幸的是,MySQL 不能像那样使用 user_id 索引,因此它似乎锁定所有表来扫描它。如果它只有一个读锁,而另一个进程正在做这样的事情,这会导致死锁:

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?

否则我想我可以使用锁定表等,但我认为这不好,所以我很好奇是否还有其他需要考虑的事情。

mysql deadlock
1个回答
0
投票

创建一个包含所需 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 连接,它不会起作用,因为我怀疑这会在组合查询期间保持表锁定。

© www.soinside.com 2019 - 2024. All rights reserved.