2016-09-26 49 views
0

假設我有一個名爲「products」的couchDB數據庫和一個帶有表單的前端。 現在,如果用戶以這種形式從這個數據庫中打開一個文檔,我想阻止其他用戶編輯這個特定的文檔。數據庫集羣 - 異步任務

通常很簡單:

-> read document from couchDB 
-> set a variable to true like: { edit : true } 
-> save (merge) document to couchDB 
-> if someone else tries to open the document he will receive an error, becaus of edit:true. 

但是,如果有什麼兩個用戶打開該文檔在準確的同一時間? 函數將被調用兩次,當第二個函數打開文檔時,他會錯誤地接收一個編輯:false,因爲第一個沒有足夠的時間來保存編輯:true。那麼如何防止這種行爲?

第一個解決方案是: 構建數組作爲數據庫請求的提示,並且不允許並行請求,因此所有請求都會一個接一個地處理。但在我看來,這是一個不好的解決方案,因爲這個系統在某些時候會慢得令人難以置信。

解決方法二: 存儲在腳本的本地陣列當前編輯文檔的documentIDs。這將工作,因爲這不是異步過程,第二個用戶會立即收到他的錯誤。

到目前爲止很好,但是,如果有一天有太多的用戶,並且這個系統應該運行在一個集羣(節點客戶端服務器,而不是數據庫) - 現在第二個解決方案不再工作了,因爲每個集羣奴隸將擁有自己的文檔ID數組。在那裏分享會在另一個異步任務結束並導致上述相同的問題。

現在我出出主意,怎麼辦大型集羣系統通常處理類似的問題?

+0

如果他們同時保存文檔,會導致衝突。所以你的解決方案都不會有用。使用更新處理程序可減少發生衝突的機率,但仍有可能。 –

回答

2

CouchDB使用MVCC保持你的數據庫的一致性。當文件正在更新時,您必須提供ID(_id)和版本號(_rev),否則您的更改將被拒絕。

這意味着,如果2客戶端閱讀版本1的文件,並都試圖編寫使用同一版本號,只有第一個將被數據庫所接受的變化。第二個客戶端將收到一個錯誤,並且它應該獲取該文檔的最新版本才能繼續。

在單節點環境中,此模型完全防止了衝突。但是,在發生複製的情況下,即使使用MVCC,也可能發生衝突。這是因爲衝突修訂在技術上可以寫入不同的節點,然後再複製到另一個節點上。在這種情況下,CouchDB將記錄衝突,您的應用程序負責解決它們。

CouchDB中有恆星的文檔,尤其是他們有an article all about conflicts and replication,我強烈建議這個主題。