我有 5 个以上的进程同时从同一个 mysql 表中选择行。每个进程选择 100 行,处理它并删除选定的行。
但是我选择并处理了 2 次或更多次相同的行。
如何避免它发生在 MYSQL 端或 Ruby on Rails 端?
该应用程序基于 Ruby On Rails 构建...
我有 5 个以上的进程同时从同一个 mysql 表中选择行。每个进程选择 100 行,处理它并删除选定的行。
但是我选择并处理了 2 次或更多次相同的行。
如何避免它发生在 MYSQL 端或 Ruby on Rails 端?
该应用程序基于 Ruby On Rails 构建...
您的表格似乎是一个工作流程,这意味着您应该有一个指示行状态的字段(在您的情况下为“已声明”)。其他进程应该选择无人认领的行,这将防止进程踩到彼此的行。
如果你想更进一步,你可以使用进程标识符,这样你就知道什么在做什么,也许工作时间太长,以及它是否完成等等。
是的,回到你的旧问题并批准一些答案。我至少看到了一个你肯定错过的。
埃里克的回答很好,但我想我应该详细说明一下......
你的表中有一些额外的列说:
lockhost VARCHAR(60),
lockpid INT,
locktime INT, -- Or your favourite timestamp.
将它们全部默认为 NULL。
然后你让工作进程通过执行以下操作“声明”这些行:
UPDATE tbl SET lockhost='myhostname', lockpid=12345,
locktime=UNIX_TIMESTAMP() WHERE lockhost IS NULL ORDER BY id
LIMIT 100
然后使用 SELECT ... WHERE lockhost='myhostname' 和 lockpid=12345 处理声明的行
处理完一行后,进行必要的更新,并将 lockhost、lockpid 和 locktime 设置回 NULL(或删除它)。
这会阻止同一行同时被多个进程处理。您需要主机名,因为您可能有多个主机在进行处理。
如果一个进程在处理批处理时崩溃,您可以检查“锁定时间”列是否很旧(比处理可能需要的时间早得多,比如几个小时)。然后,您可以只回收一些具有旧“锁定时间”的行,即使它们的锁定主机不为空。
这是数据库中非常常见的“队列模式”;它不是非常有效。如果您有非常高的项目进入/离开队列,请考虑使用适当的队列服务器。