2

私はMongoDBに比較的慣れておらず、この手法に触発されたトランザクションの実装をいじっています:

http://cookbook.mongodb.org/patterns/perform-two-phase-commits/

特定のソース/宛先アカウントの同時トランザクションをブロックする方法を考えています。たとえば、ソースを一意のインデックスとして宣言することで、同じソースでの同時トランザクションをブロックできます。

transactionsCollection.ensureIndex({"source":1}, {unique: true});
var newDoc = {source: sourceID, destination: destinationID, 
              amount: 100, state:"pending"}
transactionsCollection.save(newDoc, {safe:true}, function(error, t) {
    if (error.name == "MongoError" && error.code == 11001)
        // duplicate index, so I'm locked out
}

しかし、私が本当に望んでいるのは、ソースまたは宛先のいずれかが (ソースまたは宛先として) トランザクション テーブルに既に存在する場合にロックアウトされることです。

したがって、私の質問は、上記を許可する方法でインデックスを設定できるかどうか、またはこれを達成するために他にどのような方法があるかということです。

ありがとう!

4

2 に答える 2

2

tagsレコード内の配列 (以下) で一意のインデックスを使用すると、トリックが完了するはずです。例:

db.test.save({ name: 'one', tags: [1, 2] });
db.test.save({ name: 'two', tags: [3, 4] });
db.test.ensureIndex({ tags: 1 }, {unique: 1});

db.test.save({ name: 'three', tags: [4, 5] });
E11000 duplicate key error index: test.test.$tags_1  dup key: { : 4 }
于 2012-08-09T18:19:53.453 に答える
0

コメントに表示される質問に実際に回答する回答を実際に配置するには、ドキュメントが次のようになるように、サブドキュメントに一意のインデックスを配置することをお勧めします。

{
    _id:{},
    accounts: [1,2],
    source: 1,
    destination: 2
}

アカウント フィールドに一意のインデックスを設定すると、保留中のトランザクションに対してアカウント 1 と 2 の両方がロックされ、それが完了するまでそれ以上のトランザクションが停止されます。したがって、これは、保留中のトランザクションが存在する場合、ソースまたは宛先が 1 か 2 かに関係なく救済されることを意味します。

ただし、場合によっては、このような統合トランザクションの場合、サブドキュメントの順序を保証することはできません。次のようなトランザクションの方向を判断するためにサブドキュメントを使用することはありません。

dest_source: [1,2]

アカウント 1 がアカウント 2 に支払いを行っていることを示すには、このインデックスの順序が保存方法によって変わる可能性があるため、サブドキュメントを使用して、実際にsourceandフィールドを使用しながらインデックス内の順列を考慮したインデックス タイプを作成します。destinationドキュメントの順序が変わっても、名前付きフィールドを介して方向を理解できるため、トランザクションがどの方向に進んでいるかを理解できます。

これは、OPが実際に望んでいたことだと思います。

于 2012-08-10T07:27:53.033 に答える