Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用MySQL将任务分配给工作进程的正确方法_Sql_Mysql_Transactions_Innodb - Fatal编程技术网

使用MySQL将任务分配给工作进程的正确方法

使用MySQL将任务分配给工作进程的正确方法,sql,mysql,transactions,innodb,Sql,Mysql,Transactions,Innodb,我在MySQL InnoDB表中有一个巨大的URL列表,以及查询MySQL以获取一组要处理的URL的工作进程。URL应立即标记为正在处理,以便其他工作进程不会因为开始处理相同的URL而浪费资源 目前,我首先这样做是为了获得一些URL: SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100 然后在代码中,我天真地循环遍历每个URL,将其标记为正在处理: UPDATE urls SET tas

我在MySQL InnoDB表中有一个巨大的URL列表,以及查询MySQL以获取一组要处理的URL的工作进程。URL应立即标记为正在处理,以便其他工作进程不会因为开始处理相同的URL而浪费资源

目前,我首先这样做是为了获得一些URL:

SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100
然后在代码中,我天真地循环遍历每个URL,将其标记为正在处理:

UPDATE urls SET task_assigned = NOW() WHERE url = ? COLLATE utf8_bin

我很清楚这是多么愚蠢和低效。更重要的是,不能保证另一个工作者进程不会在我的更新过程中尝试获取列表。做这件事的好方法是什么?我应该如何使其成为事务?

也许您应该首先选择所有URL,然后使用线程异步解析它们?

以下内容(快速浏览MySQL 5手册)将在MySQL中提供:;我不确定这是否是最好的方法,但这是我以前在PostgreSQL中使用过的方法:

BEGIN TRANSACTION;
SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100 FOR UPDATE;
UPDATE urls SET task_assigned = NOW() WHERE url IN [list of URLs] COLLATE utf8_bin;
COMMIT;
实际上,在PostgreSQL中,我会使用一个UPDATE语句,其中UPDATE的RETURNING子句代替SELECT,但这是一个特定于PostgreSQL的扩展


我发现您的方法存在一个潜在问题,即重复的url:if url
http://www.example.com/
在您的表中出现两次,比如ID 23和42,SELECT将返回其中一个ID,但更新将影响这两行。我不知道这种行为在你的应用程序中是否有意义;我可能会对URL设置某种唯一的约束,这样就不会发生这种情况,然后在
in
子句中使用ID列表,而不是URL列表(这应该更快)。

实际上有几台计算机正在处理URL,我正在使用HTTP请求传递列表。谢谢。然而,你能想到一种纯SQL的方法来实现这一点,而不必首先在代码中创建逗号分隔的[URL列表]?好的,你总是可以用一个子查询替换该位(复制并粘贴SELECT语句)。我不知道那会有多好。。。实际上,可能比代码版本要好。