4

スキーマ:

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

あります":

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

および「b」:

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

a.available = false を更新する場合、b.available = false も同時に更新する必要があります。2 つのドキュメントを更新し、"a" と "b" を更新する間に他のプロセス/スレッドが "b" を取得しないようにするにはどうすればよいでしょうか。

4

2 に答える 2

5

MongoDB はアトミック トランザクションをサポートしていません。したがって、2 番目の更新が失敗した場合に最初の更新を「元に戻す」必要がある場合は、運が悪いです。

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

注意点:

  • ドキュメントはすべて同じコレクション内にある必要があります
  • 更新はすべて 1 つのクエリで指定する必要があります

あなたが提供した例に基づいて、あなたのケースは資格があるかもしれません。

これは、個別の更新について説明しているドキュメントです。

基本的に、次のような更新を発行して、名前が「a」または「b」の場合に「available」をアトミックに false に設定する必要があります。

db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false});
于 2012-05-09T15:11:53.447 に答える
3

本当に必要な場合は、このロジックを mongodb の上に実装することもできます (アプリケーション内、または mongo ドライバーのラッパー内に実装することをお勧めします)。

分離プロパティを求めています。これを実現する 1 つの方法は、MVCCパターンを使用することです。これは本当にやり過ぎですが、mongodb といくつかの ACID プロパティの両方が本当に必要な場合に何ができるかを示すためのものです。

MVCC パターンの一般的な実装については、こちらで説明しています。これを実装するためのプロジェクトが github にもありますが、これは Java プロジェクトです。

このSO の質問とその回答も表示される場合があります。私の現在の答えは、それを要約したものです。

于 2012-05-10T08:10:13.197 に答える