我使用此查询在并发工作程序之间分配行:
SET @update_id := 0;
UPDATE tablename
SET processed = -1, id = (SELECT @update_id := id)
WHERE processed = 0
LIMIT 1
SELECT @update_id as id;
有时会抛出死锁异常,我刚刚重新启动它。但是,如果工作人员数量足够多,它几乎每次都会开始陷入僵局并陷入重试循环。如何正确地重写它?
答案 0 :(得分:0)
您应该将processed
列编入索引并尝试此查询
SET @update_id := (SELECT id FROM tablename t WHERE processed = 0 LIMIT 1);
SET @updated_id := 0;
UPDATE tablename
SET processed = -1, id = (SELECT @updated_id := id)
WHERE
id = @update_id
AND processed = 0;
SELECT @updated_id as id;
你可能需要多次运行,直到你得到零updated_id。当没有未经处理的记录时,你需要处理这种情况。
替代方法:
假设每个进程都有一个唯一的@process_Id,它一次只处理一个记录并删除它,或者在处理后将处理设置为-1。
UPDATE tablename SET processed = @process_id WHERE processed = 0 LIMIT 1;
SELECT id FROM tablename t WHERE processed = @process_id;