同时运行多个PHP脚本(数据库循环问题)

时间:2011-11-20 01:16:45

标签: php mysql sql database

我正在同时运行10个PHP脚本,并在Linux上的后台进行处理。

例如:

while ($i <=10) {
 exec("/usr/bin/php-cli run-process.php > /dev/null 2>&1 & echo $!");
 sleep(10);
 $i++;
}

run-process.php中,我遇到数据库循环问题。其中一个进程可能已经将status字段更新为1,似乎其他PHP脚本进程没有看到它。例如:

$SQL = "SELECT * FROM data WHERE status = 0";
$query = $db->prepare($SQL);
$query->execute();

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $SQL2 = "SELECT status from data WHERE number = " . $row['number'];
    $qCheckAgain = $db->prepare($SQL2);
    $qCheckAgain->execute();
    $tempRow = $qCheckAgain->fetch(PDO::FETCH_ASSOC);

    //already updated from other processs?
    if ($tempRow['status'] == 1) {
        continue;
    }

    doCheck($row)
    sleep(2)
}

如何确保流程不会再次重新执行相同的数据?

4 个答案:

答案 0 :(得分:3)

当您有多个进程时,您需要让每个进程获取某组记录的“所有权”。通常,您可以通过使用limit子句进行更新,然后选择脚本“刚”拥有的记录来执行此操作。

例如,有一个字段指定记录是否可用于处理(即值为0表示它可用)。然后,您的更新会将字段的值设置为脚本进程ID,或者该进程的其他唯一编号。然后选择进程ID。完成处理后,您可以将其设置为“已完成”的数字,例如1.更新,选择,更新,重复。

答案 1 :(得分:1)

您的脚本多次执行相同查询的原因是您正在创建并行化。进程1从数据库中读取,进程2从数据库中读取并且都开始处理它们的数据。

数据库提供交易以摆脱这种竞争条件。查看PDO provides处理数据库事务的内容。

答案 2 :(得分:1)

我不完全确定您正在处理的方式/内容。

您可以引入limit子句并将其作为参数传递。因此,第一个进程首先执行10,第二个进程执行下一个10,依此类推。

答案 3 :(得分:0)

你需要锁定,例如“SELECT ... FOR UPDATE”。

innodb支持行级锁定。

有关详细信息,请参阅http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html