我有一個使用數據庫來同步客戶端的分佈式應用程序。客戶將嘗試更新記錄,但只有在過去1小時內沒有其他客戶這樣做時纔會這樣做。如何以時間戳原子更新一行?
這裏是縮小的代碼和困境:
說一個客戶端嘗試更新的字段「紅」(檢查沒有其他人在過去一小時內更新它):
UPDATE mytesttable
SET Status = 'Red',
TimeOfLastUpdate = sysdate
WHERE TimeOfLastUpdate < sysdate-1/24
,並在同一時間,另一客戶端嘗試更新其爲「綠色」(檢查沒有其他人在過去一小時內更新它):
UPDATE mytesttable
SET Status = 'Green',
TimeOfLastUpdate = sysdate
WHERE TimeOfLastUpdate < sysdate-1/24
我能否假設只有一個客戶端才能成功更新該行?
這也是爲什麼我認爲答案是「不」:
因爲Oracle必須解決前sysdate
它獲得的行級更新鎖(因爲它必須使用它來查找行第1名),它似乎有一個競爭條件:
- 客戶端「紅」計算
sysdate
- 客戶「綠色」計算
sysdate
- 1小時傳遞
- 客戶端 「紅」 的更新
TimeOfLastUpdate
與舊sysdate
- 客戶端的 「綠色」 與舊
sysdate
更新TimeOfLastUpdate
(由此更新兩次)
我是正確識別此作爲競賽條件?如果不是,我錯過了什麼?
如果是這樣,是否有一個有效的,更可靠的解決這個問題?
雖然不完全是你的問題,但我認爲接受的答案也是我對你的建議。如果您絕對必須確保只有一個人更新它,請使用序列。 http://stackoverflow.com/questions/8498169/race-condition-between-select-and-update –