[英]Simultaneous running cron jobs records processing mix
我正在為多個同時吃午飯的 cronjobes 相同的記錄過程問題而苦苦掙扎
介紹
問題是當 10 個 cronjobes 同時啟動時隨機發生 2 個 cronjobes 從數據庫中選擇相同的客戶進行處理
因此,這意味着 2 個 cron 幾乎在同一時間開始(微秒差異),它們都是在同一時間從數據庫中選擇最后一個未處理的行(例如 id:17),然后在數據庫中更新相同的 id17 第三次午餐 cronjobe 已經采用了 id:18。 但我需要每個 coronjobe 都會從不同的數據庫中獲取唯一的下一條記錄
As a workaround i tried to add random sleep(rand(1,10)) delay at beginning of cron.php but don't help mutch, random duplication still happens cause cron continuously selects last unprocessed next customer which sometime matches with another cornjobe next customer select at same time
有沒有針對這種情況的解決方案???
您尋求的解決方案是協作鎖定。 客戶必須被某個作業標記為“鎖定”,並且沒有腳本必須選擇被另一個腳本鎖定的客戶。
此外,您必須以這樣一種方式做到這一點,即沒有兩個工作選擇同一個客戶來獲取。
在 MySQL 中,您可以執行以下操作:
$me = getmypid();
$conn->execute("SELECT GET_LOCK('choosing', 5) AS okay");
// Check the returned value of okay. If it is not 1, exit() immediately.
// choose some customer in some way. The smallest Id with OwnedByPid=0 for example. The query should be fast enough to run in under 5 seconds.
$conn->execute("UPDATE customers SET OwnedByPid={$me} WHERE id={$custId};");
$conn->execute("SELECT RELEASE_LOCK('choosing'");
//
// Do your work
$conn->execute("SELECT GET_LOCK('choosing', 5)");
$conn->execute("UPDATE customers SET OwnedByPid=0 WHERE OwnedByPid={$me};");
$conn->execute("SELECT RELEASE_LOCK('choosing')");
然后,定期 - 當沒有腳本運行時 - 釋放可能被崩潰的腳本標記的客戶:
$conn->execute("UPDATE customers SET OwnedByPid=0;");
或者您可以添加另一列,OwningStart,在您取得所有權時將其設置為 NOW(),這樣您就可以檢查 OwningStart 何時超過 30 秒並清除它。 或將其標記為免費:
SELECT MIN(Id) FROM customers WHERE OwnedByPid=0 OR OwningStart < NOW() - INTERVAL 2 MINUTE;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.