我被赋予了创建一个" Mass Crawler"它完全依赖于数据库中的代理。以下是我试图实现的简单概述:
我已经使用mySQL查看TRANSACTIONS
,但我仍然相信这样做无助于查询将在每个爬网程序进程的同一时间执行
以下是我个人抓取文件的想法:
$db = new MysqliDb("localhost", "username", "password", "database");
$db->connect();
$db->startTransaction();
$db->where("last_used", array("<" => "DATE_SUB(NOW(),INTERVAL 30 SECOND)"));
$proxies = $db->get("proxies", 1);
if(count($proxies) == 1) {
//complete any scraping that needs to be done
//update the database to say the proxy has just been used
$db->where("id", $accounts[0]['id']);
$db->update("proxies", array("last_used", date("Y-m-d H:i:s")));
//commit the complete transaction
$db->commit();
}
$db->disconnect();
以上示例是否是使用mySQL TRANSACTION
功能的正确方法,并确保选择不同行的所有并行查询?
答案 0 :(得分:3)
表中需要一个列,指示某个爬网程序进程正在使用该行。您的第一个SELECT
应该查找WHERE in_use = 0
;但是,它需要使用FOR UPDATE
子句来锁定已处理的行。
SELECT *
FROM proxies
WHERE in_use = 0
LIMIT 1
FOR UPDATE;
我不知道如何使用您正在使用的数据库API编写该查询;您可能需要使用其功能来执行原始查询。
然后将该行更新为SET in_use = 1
。通过在事务中执行这两个操作,可以确保没有其他进程可以获取该行。
处理完行后,可以SET in_use = 0
。