2015-12-21 108 views
0

我使用PHP + JS創建遊戲。每場比賽都是人vs人,所以只有2個用戶。它有效,但我在「雙重預訂」方面遇到麻煩。就像這樣:防止雙重執行PHP + JS

  1. 用戶1創建遊戲#10(PHP)
  2. 遊戲大廳(JS)最多顯示
  3. 用戶2加入遊戲#10(PHP)
  4. 用戶3加入遊戲#10(PHP )
  5. 遊戲從大廳(JS)

的步驟3和4之間僅發生毫秒消失。當用戶加入遊戲時,我首先檢查是否採取了「座位」。如果沒有 - 我解析所有基本數據等,然後我設置了座位。在解析過程中,用戶似乎可以加入同一個遊戲。正如我前面所述,這是毫秒級的問題。但我如何防止這種情況?

+0

也許某種排隊? – Rasclatt

+0

踢出最後加入的用戶? – Andrew

+0

沒有什麼可以做客戶端的。你需要在服務器上做適當的鎖定/看門。例如在處理用戶#2的請求時鎖定相應的數據庫記錄,並且在完成所有準備工作之前不要解鎖它。當這些完成後,你解鎖,用戶#3的請求開始得到處理,並注意到「嘿,這個遊戲已經完成了」。 –

回答

0

你可以使用一個隱含的數據庫記錄鎖,通過利用免費的座位,這樣的事情在執行一種test-and-set操作:

UPDATE blackjack_hands 
SET user_id = :user_id 
WHERE user_id IS NULL 
AND blackjack_id = :blackjack_id 
AND creator = '0'; 

然後檢查更新的記錄數(例如用msqli_affected_rows),然後決定座位是否成功(這意味着它是免費的)。

這樣,第二個用戶不可能進行同樣的成功更新。

這將是一個悲觀鎖定的例子。

上面的查詢假設在遊戲創建過程中,您會立即插入兩條記錄,一條用於創建者的user_id(正如您已經這樣做),另一條用於未知對手的user_id,初始化爲NULL。

注意:考慮從已棄用的mysql_*函數中移開。您可以使用mysqli_*PDO接口。