2012-05-09 84 views
4

模式:MongoDB中更新多個文檔

{ 
    name: String, 
    available: Boolean, 
    for: String 
} 

有 「一」:

{ 
    name: "a", 
    available: true, 
    for: ["b", "c"] 
} 

和 「b」:

{ 
    name: "b", 
    available: true, 
    for: ["a", "b] 
} 

如果我更新a.available =假,我應該同時更新b.available = false。 我怎麼能更新兩個文件,並確保在更新「a」和「b」之間不會有其他進程/線程獲得「b」。

回答

5

MongoDB不支持原子事務。因此,如果您需要在第二次更新失敗時進行第一次更新「自行撤消」,那麼您的運氣不佳。

但是,在某些有限的情況下,MongoDB確實支持隔離更新。更新不是全部或沒有,但MongoDB將保證沒有其他人在寫入過程中寫入集合。

一對夫婦的主要注意事項:

  • 的文件都必須是同一個集合
  • 的更新都必須在一個查詢

基於這個例子中你可以指定在已經提供,你的情況可能有資格。

Here是描述孤立更新的文檔。

基本上你會想發出類似下面以原子設置爲「可用」,以虛假的更新操作時,名稱是「A」或「B」:

db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false}); 
+0

如果我想用不同的值自動更新不同的文檔。如果name ==「a」,則更新計數= 1;如果name ==「b」,則更新計數= 2。 – Kevin

+0

這可能不可能。正如我所說的,這個功能有一些重大的限制 - MongoDB並不是真正爲此設計的。 –

3

如果你真的需要它,可以在mongodb之上實現這個邏輯(在你的應用程序中或在mongo驅動程序的包裝器中更好)。

您要求隔離屬性。一種方法是通過使用MVCC模式。這真是太過於誇張了,但這是爲了讓你知道如果你真的需要mongodb和一些ACID屬性你可以做什麼。

MVCC模式的通用實現描述here。在github上也有一個project來實現這個,但它是一個java項目。

您可能還會看到這SO question和他們的答案。我現在的答案只是它的一個總結。