2011-11-04 94 views
0

我有5+同时从同一个mysql表中选择行。每个进程选择100行,处理它并删除选定的行。
如何在Mysql中原子选择行?

但是我得到了同样的行选择和处理2次或更多。

如何避免它发生在MYSQL端或Ruby on Rails端?

这个应用程序是建立在Ruby on Rails的...

回答

4

你的表似乎是一个工作流程,这意味着你必须有一个字段表示状态(在你的情况下“声称”)。其他进程应该选择未声明的行,这将防止进程踩在彼此的行上。

如果你想采取了一步,你可以使用的进程标识符,让你知道什么是什么工作,也许多久过长是工作,以及是否它的完成,等

是的,回到你的旧问题,并批准一些答案。我看到至少有一个你肯定错过了。

3

Eric的回答是好,但我觉得我应该制定一个有点...

您的表中的一些附加列说:

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(或删除它)。

这会停止同一行被多个进程同时处理。您需要主机名,因为您可能有多个主机正在处理。

如果进程在处理批处理时崩溃,可以检查“锁定时间”列是否非常旧(比处理可能需要的时间要早​​几个小时)。然后你可以回收一些具有旧的“锁定时间”的行,尽管它们的锁定主机不为空。

这是数据库中相当常见的“队列模式”它并不是非常有效。如果您的项目进入/离开队列的比率非常高,请考虑使用适当的队列服务器。