我正在同时运行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)
}
如何确保流程不会再次重新执行相同的数据?
答案 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。