2012-07-16 82 views
2

我使用的Web應用程序pymongo,和想要做的形式的東西鎖定一個文件:MongoDB中

doc = collection.find(document) 
doc.array1.append('foo') 
for(y in doc.array2): <do things with y> 
doc.array2 = filter(lambda x: ..., doc.array2) 
doc.x = len(doc.array2) 
collection.save(doc) 

有沒有什麼簡單的方法,這樣我可以處理處理同一文檔的多個請求並防止他人破壞另一個/的結果無效,因爲它正在編輯一個陳舊的版本?

回答

2

看看在MongoDB的文檔的部分上Atomic Operations

,可能是你的興趣的部分是關於更新,如果它仍然是當前的部分。

  1. 獲取對象。
  2. 在本地修改對象。
  3. 發送一條更新請求,指出「如果該對象仍然與舊值相匹配,則將該對象更新爲此新值」。

如果操作失敗,那麼我們可能需要從步驟1

這是當你有一些操作的執行方法再試一次,你想避免持有鎖在數據庫上。他們還在該文件中聲明他們通常如何抵制鎖定。

+0

我看到他們如何反對持有鎖,但我認爲這是爲收集而不是單個文件?我希望有一種方法可以執行此操作 2012-07-17 00:03:12

+0

該文檔通過基本的'update'查詢或更復雜的'find and modify'命令解釋了這樣做的方法。這個問題是基於你的例子,你首先要對文檔數據做一堆本地操作來確定新的修改值。這需要能夠將文檔從客戶端保持在鎖定狀態。他們不允許這種功能,因爲他們表示可能導致潛在的死鎖(如果說你的應用程序突然終止)。 – jdi 2012-07-17 00:12:46

+0

MongoDB(特別是PyMongo)是否有一個內置構造來執行此操作@jdi還是必須手動執行此操作?似乎無法找到。 – Ali 2015-10-06 09:59:02

0

您可以在應用程序級別實現文檔鎖定。

使用場景:

with DocumentLock(doc_id): 
    # DocumentLock makes sure no other thread interferes 
    doc=db.doc_collection.find_one(doc_id) 
    ... # analyse and update the document 
    db.doc_collection.save(doc) 

我實現DocumentLock類的多線程應用程序並公佈它here

悲觀鎖定更容易比official docs建議樂觀鎖定使用。在certain conditions下效率更高(在其他情況下效率可能非常低,所以在使用之前必須考慮和評估)。