2016-09-26 119 views
0

我試圖阻止用戶在「同一時間」加入選擇相同的可用管理員。PHP防止MySQL競爭條件

我在做什麼是:

$conn->beginTransaction(); 

$sth = $conn->query("SELECT admin,room FROM admins WHERE live = 1 AND available = 1 ORDER BY RAND() LIMIT 1 FOR UPDATE"); 
$free_admin = $sth->fetch(); 

if (!empty($free_admin)) { 

    $conn->query("UPDATE admins SET available = 0 WHERE room = " . $free_admin['room']); 

    . 
    . 

    $conn->commit(); 

} else { 

    $conn->rollBack(); 
} 

可惜這不是真正的工作。當流量很高時,許多用戶最終會選擇導致問題的相同免費管理員。

如何鎖定SELECTED行,以便在任何其他用戶可以讀取它之前,只讀一個用戶來更新它?

+1

您應該使用[bindValue/bindParam](https://secure.php.net/manual/en/pdostatement.bindvalue.php)查看綁定動態值以避免SQL注入。 – Chris

+1

@Chris丫我會的,這段代碼只是爲了測試,以克服競爭條件問題 –

+0

@ e4c5我不知道我理解你的問題。我想要做的是選擇一個隨機可用的管理員。如果有,請將其設置爲不可用。這怎麼能做得更好? –

回答

0

在updatestatement,使用

WHERE room = ... AND availabe = 1 

查詢後,檢查MySQL的affected_rows來驗證你沒有成功地改變可用性,如果沒有,重新啓動。

+0

我明白你的解決方案。我已經厭倦了,不幸的是這並沒有解決問題。 –

+0

你確認你有受影響的行嗎?並重新選擇,如果你沒有?如果是這樣,它不可能是一些其他進程從你身上偷走它(除非你使用某種形式的緩存或從屬數據庫) – andre