2009-06-18 54 views
5

我承認我不是100%的PDO和MySQL的內部工作,所以我會舉一個例子讓我的問題更清晰。有沒有辦法迫使PHP等待MySQL完成事務處理?

我正在製作一個相當粗糙的基於瀏覽器的戰略遊戲,因爲我認爲這是學習PHP和數據庫的有趣方式。當我遇到一個意想不到的錯誤時,我正在測試戰鬥腳本。我使用Cron Jobs每分鐘調用腳本,看起來像這樣:

$ sql =「SELECT army_id FROM activearmy WHERE arrival = 0;」;

foreach($dbh->query($sql) as $row) 
    { 

     battleEngine($row["army_id"]); 

    } 

當基本的計算完成(進攻的軍隊保衛主場迎戰軍隊),數據庫中的六個表進行更新。我面臨的問題是,當我在同一分鐘內對同一個目標進行多次攻擊時,其中一次或一次攻擊會獲取過時的數據庫信息(在極端情況下,攻擊#10獲取與攻擊5相同的表) 。

我猜這是因爲腳本比數據庫更快?有沒有一種方法可以強制PHP等到所有相關信息都到位之後再用下一個$行重複該函數?

編輯:埃米爾可能是正確的。我無法確定,因爲我的PDO似乎不可能保持足夠長的時間,以便在beginTransaction()和commit()之間傳遞幾條語句。然而,由於我使用InnoDB和「REPEATABLE READ」,髒讀看起來很奇怪。一些谷歌搜索建議REPEATABLE READ將使髒讀不可能。在考慮如何自殺一段時間之後,我選擇了黑客。現在,我在我的腳本上放置了一個特殊值的UPDATE,另一個放在底部的大批量(大約6個UPDATE語句)的末尾。在運行該函數之前,我已經建立了一個while() - 循環來檢查特殊值是否被設置爲0.如果不是,它會休眠0.01秒,然後再試一次。看着輸出,while循環平均重複兩次,表明它可能實際上在工作?它還沒有失敗,但可能是因爲它不是高峯時段。我明天定期再試一次。我知道沒有人關心這一切,但我覺得我應該做這個更新以防萬一。 = P

回答

1

如果PHP只是完全等待,那麼您會得到大量的cron作業。

你想要什麼想要使用類似於anachron的東西,以確保在任何給定時刻只有一個腳本實例運行。您也可以執行以下操作:

<?php 

    if (file_exists('/tmp/myscriptlock')) exit(); 
    touch('/tmp/myscriptlock'); 

    // do your stuff 

    unlink('/tmp/myscriptlock'); 
+0

srry爲格式不好 – Evert 2009-06-18 23:04:18

+1

這將是更好的使用MySQL鎖,這樣,如果作業,從而連接死亡鎖自動釋放。 http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock – 2009-06-18 23:06:44

1

您所看到的內容稱爲「髒讀」。使用InnoDB並將isolation level設置爲可序列化。然後將所有查詢包含在事務塊中:

$dbh->beginTransaction(); 
// run queries 
$dbh->commit();