[英]Incorrect Value Being Retrieved from the Database
情況:我創建了一份工作。 這是將客戶輸入的訂單添加到API。 我將其設置為每隔一分鍾運行一次。
問題:有時,當待處理的訂單太多時,第二個Cron作業在第一個Cron作業結束之前被調用。 這導致通過API發送的重復訂單。
解決方案:我在數據庫中創建了一個名為cron_jobs的表。 它有兩列,ID和狀態。 運行cron作業時,它將檢查狀態是否為0。 如果狀態為0,則將狀態更新為1。完成其過程,並將狀態再次標記為0。如果作業的狀態為1(表示它已經在運行),然后再次單擊它,則操作為終止。
意外故障:此解決方案在邏輯上似乎正確。 但是當我實現它時,結果令人震驚。 運行作業時,其狀態將更新。 但是,當再次調用它時,數據庫仍然返回狀態0,並且繼續執行。 我還使用了睡眠方法,以便有足夠的時間來調查問題。 但是數據庫總是返回比使用phpmyadmin所看到的錯誤的值。
請不要以為我可能犯了一些愚蠢的錯誤。 在完全調用第一個實例之前,文件的第二個實例始終獲取錯誤的值。 看一下我的代碼:
<?php
$Output = mysql_fetch_assoc(mysql_query("select status from jobs where ID='1'"));
if($Output['status'] == '0')
{
mysql_fetch_assoc(mysql_query("update jobs set status='1' where ID = '1'"));
mysql_fetch_assoc(mysql_query("update jobs set invoked = invoked+1 where ID = '1'"));
echo 'Executed';
}
else
{
echo 'Error: Another cron job already in process. Operation terminated!';
die();
}
/*I perform some lengthy tasks here*/
/*Sleep function called to check whether another instance of the program works while this one is in progress */
sleep(60);
/*Task is complete. We are marking 0 as status so that another instance is allowed to work on.*/
mysql_fetch_assoc(mysql_query("update jobs set status='0' where ID = '1'"));
?>
觀察1 :如果我在另一個瀏覽器或另一台計算機上運行第二個實例,它會很好地工作。
觀察2 :我試圖調查是否確實被多次調用。 我在表中的另一列為“ No_Of_Times_Invoked”。 我發現當我在同一瀏覽器中使用該代碼時實際上失敗了。
您的SELECT
查詢使用表cron_jobs
。 其他每個查詢都使用jobs
。 我相信您的SELECT
查詢失敗,導致mysql_query()
返回false
。
$Output = mysql_fetch_assoc(mysql_query("select status from cron_jobs where ID='1'"));
由於mysql_query()
在此返回false
,因此mysql_fetch_assoc()
也返回false
。
if($Output['status'] == '0')
$Output
為false
。 在PHP中,當使用==
,可以進行類型轉換。 在這種情況下, $Output['status'] == '0'
計算結果為true
。 (請注意, $Output['status']
為null
,但null == '0'
計算結果為false
。 雜耍類型和松散比較的樂趣。)
將查詢替換為
SELECT `status` FROM jobs WHERE ID = '1'
它應該運行正常。
我確實建議對mysql_*()
函數的返回值添加更多的錯誤檢查(使用$returnValue === false
),或者甚至更好地切換到PDO 。
經過評論中的一些討論后更新
似乎問題是您正在通過瀏覽器進行測試。 至少Firefox 23.0.1(我用於測試)在第一個請求完成之前不會發送第二個請求。 這將解釋您看到的所有行為。 新的瀏覽器或計算機將無法重新使用該連接,因此在這種情況下它可以工作。
如果我從命令行兩次啟動腳本(相隔五秒鍾),它將正常運行:第二次運行輸出Error: Another cron job already in process. Operation terminated!
Error: Another cron job already in process. Operation terminated!
。
請注意,PHP確實抱怨每個mysql_query("update ...")
函數調用周圍都有無效的mysql_fetch_assoc()
:
警告:mysql_fetch_assoc()期望參數1為資源,在/test/test.php的第7行中給出布爾值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.