【发布时间】:2013-12-28 21:16:36
【问题描述】:
我有一个包含电子邮件列表和自动递增 ID 的表格,在该表格上完成了索引。
CREATE TABLE EMAIL_LIST
(
ID int NOT NULL AUTO_INCREMENT,
email_ID varchar(255),
lastFetchedID int,
PRIMARY KEY (ID)
);
CREATE INDEX PIndex ON EMAIL_LIST (ID);
然后我有多台计算机唯一地获取 email_ID,这样做是为了扩展获取过程。 但要获取的 email_ID 是有条件描述的。
SELECT lastFetchedID FROM EMAIL_LIST WHERE ID=1 FOR UPDATE; // say this is x;
UPDATE EMAIL_LIST SET lastFetchedID=lastFetchedID+100 WHERE ID=1;
SELECT email_ID FROM EMAIL_LIST WHERE ID>=x AND ID< x+100;
这样每台计算机都有一组不同的 email_ID
我只是想知道我是否使用 select 进行更新,并且在同一连接中,如果我获取 100 个 email_ID,整个事务中 ID=1 的行是否会有排他锁?
实现这一目标的最佳方法是什么,计算机的数量可能会有所不同,所以我正在这样做。
【问题讨论】:
-
就我个人而言,我认为您是从错误的方向解决问题,而不是让工作人员拆分工作,而拥有一个为您拆分工作的主流程会更方便。如果您提前知道工作人员的数量,这很容易做到,您甚至可以创建一个单独的表,其中包含工作,每个工作人员都可以通过这种方式从数据库中获取特定的结果集。
-
lastFetchedID 是任何一台计算机获取 email_ID 之前的 ID,任何一台计算机一次获取 100 个 email_ID。所以第一台任何计算机都会更新 lastFetchedID 值,然后获取 100 个 email_ID。
-
@Wolph 计算机的数量可能会有所不同,并且该表有数百万个 email_ID。如果我知道计算机的数量,我可以简单地使用 ID 模数
-
有关 InnoDB 在事务期间如何锁定的信息,请参阅 dev.mysql.com/doc/refman/5.5/en/innodb-transaction-model.html。
-
@user2368055:在这种情况下,让一台计算机创建“作业”仍然是个好主意。让它创建具有给定批量大小的批次(任何适当的大小都应该这样做)并将它们添加到具有
begin_id和end_id的作业表中。每个工人都可以简单地循环并一次从作业表中取出 1 行,直到它为空。