Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.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
同时运行多个PHP脚本(数据库循环问题)_Php_Mysql_Sql_Database - Fatal编程技术网

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

同时运行多个PHP脚本(数据库循环问题),php,mysql,sql,database,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++; } $SQL = "SELECT * FROM data WHERE status = 0"; $query = $db->prepare($SQL); $query->e

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

例如:

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

如何确保进程不再重复执行相同的数据?

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


数据库提供事务以消除这种竞争条件。请看一下处理数据库事务的
PDO

我不完全确定您是如何处理的


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

当您有多个进程时,您需要让每个进程“拥有”一组特定的记录。通常通过使用limit子句进行更新,然后选择脚本刚刚“拥有”的记录来实现

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

您需要锁定,例如“选择……进行更新”

innodb支持行级锁


有关详细信息,请参阅。

尝试使用mysql事务。示例:如果查询没有任何参数,调用
prepare()
只会增加不必要的开销。相反,您可以使用
$db->exec($SQL)我使用了第二个sql查询来查询类似的竞争条件-它检查
status=1
,然后跳过它。我会调查数据库事务,谢谢。将
状态更新为1时是否需要添加数据库事务?这发生在
doCheck($row)
函数中(请参见我的问题)我刚刚阅读了数据库事务,如果我理解正确,我是否需要在while循环之前添加beginTransaction(),在while循环中添加commit()?我在
数据
表中有100000多行-如何计算每个进程的限制?比如说10个过程。我不知道你说的“用限制条款更新”是什么意思?基本上你的意思是,我可以添加一个名为like
run\u by
的字段,其值将是
Robot-a
Robot-B
Robot-C
-前10000行将用于
Robot-a
处理?是的。因此,您的查询将是UPDATE table SET run_by=“ROBOT-A”WHERE run_by=“UNPROCESSED”LIMIT 10000。从run_by=“ROBOT-A”所在的表中选择*。然后,当处理完成时,更新表集run_by=“PROCESSED”WHERE run_by=“ROBOT-A”。MySQL处理记录的争用问题。如果使用InnoDB,则需要在更新之前发出锁表(然后解锁)。