2011-12-09 20 views
1

如何確保用戶a在用戶b訪問用戶a的數據時手動更新他的某些信息,訪問該信息的用戶b獲取正確的更新信息而不是用戶a的陳舊數據。當用戶更新時,確保一個用戶的select語句對另一個用戶是正確的?

我明白事務很好,行級鎖定,我只是想確保我做得正確!

當更新我使用的用戶一個信息,

$dbc -> beginTransaction(); 
$dbc -> query("SELECT id FROM accounts WHERE id = " . $user['id'] . " FOR UPDATE LIMIT 1"); 
$q = $dbc -> prepare("UPDATE accounts SET name = ?"); 
$q -> execute(array($_POST['name'])); 
$dbc -> commit(); 

使用上面確實該鎖的用戶一個數據,這樣,當用戶B得到他的數據,用戶一用,

$q = $dbc -> ("SELECT * FROM accounts WHERE id = ?"); 
$q -> execute(array($_GET['id'])); 

他會得到正確的更新數據?或者在獲取用戶a的用戶數據時需要使用事務?

我對所有這些鎖和東西都有點困惑,因爲你可能知道嗎?!?

感謝

+0

行將**寫* *只要更新持續,即可鎖定。用戶B會得到正確的數據嗎?取決於他們訪問數據的時刻。您必須意識到併發訪問意味着「我們時間如此接近以至於看起來像是在同一時間」。 – Alfabravo

+0

是否沒有辦法執行用戶-b的select語句來查看用戶-a的信息,該信息只在行未鎖定時執行? – cgwebprojects

+0

它不會幫助你,因爲你不知道用戶A是否已經執行了更新,是嗎? – Alfabravo

回答

0

要在網站上,哪裏有客戶&數據庫之間的脫節處理併發,通常的做法是會對每一個可以讓你檢查後還沒有被更新記錄的列你最後得到它。

無論是上次更新日期列還是(我的首選項)自動增量版本號(通過觸發器實現),您只需檢查您的WHERE子句,即獲得的值與記錄中的值匹配,例如:

UPDATE accounts SET name = ?, lastupdate=sysdate WHERE id = ? AND lastupdate = ? 

如果lastupdate值不匹配,並且因此無法更新記錄,則可以假定數據已由其他人更新並相應地處理異常。

這適用於過度更新很少的系統。

我更喜歡使用觸發器,因爲爲您維護了併發值。 (唯一的缺點是,你必須重新查詢數據,如果你想重新更新相同的記錄,那就是直到MySQL的執行返回的條款)

看到:影響Handling the concurrent request while persisting in oracle database?

相關問題