2011-11-20 74 views
3

我在同一時間運行10個PHP腳本,並在Linux上在後臺處理它。同時運行多個PHP腳本(數據庫循環問題)

例如:

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

嘗試使用mysql事務。 示例:http://stackoverflow.com/questions/2708237/php-mysql-transactions-examples –

+0

另外,如果你的查詢沒有任何參數,調用'prepare()'只會增加不必要的開銷。相反,你可以使用'$ db-> exec($ SQL);' –

回答

3

當您有多個進程時,您需要讓每個進程都擁有某組記錄的「所有權」。通常,您通過使用限制條款進行更新來完成此操作,然後選擇腳本僅「擁有」的記錄。

例如,有一個指定記錄是否可用於處理的字段(即值爲0表示它可用)。然後,您的更新會將該字段的值設置爲腳本進程標識或進程的其他唯一編號。然後你選擇進程ID。完成處理後,可以將其設置爲「已完成」編號,例如1.更新,選擇,更新,重複。

+0

我不確定「限制條款更新」是什麼意思?所以基本上你的意思是我可以添加一個名爲'run_by'的字段,其值將是'Robot-A','Robot-B','Robot-C' - 前10,000行將用於'Robot-A'處理? –

+0

是的。所以你的查詢將是UPDATE表SET SET RUN_BY =「ROBOT-A」WHERE run_by =「UNPROCESSED」LIMIT 10,000。SELECT * FROM表WHERE run_by =「ROBOT-A」。然後當處理完成UPDATE表SET SET run_by =「PROCESSED」WHERE run_by =「ROBOT-A」。 MySQL處理記錄的爭用問題。如果使用InnoDB,則需要在UPDATE(然後解鎖)之前發出LOCK TABLE。 –

1

您的腳本多次執行相同查詢的原因是您正在創建的並行化。進程1從數據庫中讀取,進程2從數據庫中讀取數據,並開始處理其數據。

數據庫提供交易以擺脫這種競爭條件。看看用於處理數據庫事務的是什麼PDOprovides

+0

我已經使用了第二個sql查詢來處理競爭條件 - 它檢查'status = 1'是否跳過它。我會研究數據庫事務,謝謝。更新'status'爲1時是否需要添加數據庫事務?這發生在'doCheck($ row)'函數中(請參閱我的問題) –

+0

我剛剛閱讀了數據庫事務,如果我理解正確,是否需要在while循環前添加beginTransaction(),並在while循環中添加commit()? –

1

我不完全確定你正在處理的是/如何。

您可以引入限制條款並將其作爲參數傳遞。所以第一個過程先做10,第二個過程做下一個10,等等。

+0

我在'data'表中有超過100,000行 - 如何計算每個進程的限制?讓我們說10個進程。 –