2012-05-09 20 views
4

スキーマ:、MongoDBの更新複数のドキュメント

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

私は偽= a.available更新する場合:

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

と "B":

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

"A" があります私はb.available = falseを同時に更新するべきです。 2つのドキュメントを更新して、 "a"と "b"を更新する時点の間に他のプロセス/スレッドが "b"になっていないことを確認できますか?

答えて

5

MongoDBはアトミックトランザクションをサポートしていません。したがって、2回目のアップデートが失敗した場合に最初のアップデートを "元に戻す"必要がある場合、あなたは不運です。

ただし、一部の限られたケースでは、MongoDBは独立した更新をサポートしています。更新はすべてではありませんが、MongoDBは誰もあなたの書き込みの途中でコレクションに書き込むことを保証しません。

主要警告のカップル:文書がすべて同じコレクションに

  • アップデートでなければなりません

    • は、すべてあなたが例に基づいて1つのクエリ

    で指定する必要がありますあなたのケースが適格になるかもしれません。

    Hereは、隔離されたアップデートを説明するドキュメントです。基本的には

    名前がいずれかの「A」又は「B」の場合にはfalseをアトミックに設定されている「利用可能」に次のような更新を発行することをお勧めします:

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

    異なる文書を異なる値でアトミックに更新する方法name == "a"の場合、更新カウント= 1。 name == "b"の場合、更新回数= 2です。 – Kevin

    +0

    これはおそらく不可能です。私が言ったように、この機能にはいくつかの重要な制限があります.MongoDBは実際にはそういったもののために設計されていません。 –

    3

    は、あなたが本当にそれを必要とする場合このロジックをmongodbの上に実装することは可能かもしれません(アプリケーションでは、mongoドライバのラッパーでより良い)。

    あなたは分離プロパティを要求しています。これを達成する1つの方法は、MVCCパターンを使用することです。これは本当に不幸ですが、これはmongodbといくつかのACIDプロパティが本当に必要な場合に、あなたができることのアイデアを与えることです。

    MVCCパターンの一般的な実装については、hereと記載されています。これを実装するためのgithubにはprojectもありますが、これはJavaプロジェクトです。

    このSO questionとその回答も表示されます。私の現在の答えはそれを要約したものに過ぎません。

    関連する問題