7

私のserver/server.jsで

Meteor.methods({
    saveOnServer: function() {
        var totalCount = Collections.find({
            "some": "condition"
        }).count();
        if (totalCount) {
            var customerId = Collections.update('someId', {
                "$addToSet": {
                    objects: object
                }
            }, function(err) {
                if (err) {
                    throw err;
                } else {
                    return true;
                }
            });
        } else {}
    }
});

saveOnServer() が 2 つのクライアントから同時に呼び出されると、クライアントごとに同じ totalCount が返され、基本的に同じ整数がオブジェクト ID に挿入されることになります。最終的な目標は、サーバー側に行を挿入することです。アトミック操作は、totalCountが正常に返され、ドキュメントが挿入され、重複する ID が存在しないことを確認した場合にのみ完了します。mongodb _id を使用しないようにしていますが、独自の整数インクリメント id 列を使用しています。

挿入操作ごとにフィールドが自動インクリメントされるようにするにはどうすればよいでしょうか? 現在、ドキュメントの総数を取得することに依存しています。ここで競合状態は可能ですか? もしそうなら、これに対処する流星の方法は何ですか?

4

3 に答える 3

9

Meteor の同時実行モデルでは、メソッド全体を、発生する割り込み不可能なブロックと考えることができます。Meteor が途中で 1 つのメソッドの実行から別のメソッドの開始に切り替えるには、「譲歩」する必要があります。メソッドは「中断される可能性があります」というシグナルを送る必要があります。

メソッドは、何か非同期の処理を行うたびに生成されます。これは、実際には、Meteor 0.6.5 以降でデータベースの更新を行ったり、コールバックを使用してメソッドを呼び出したりすることを意味します。update呼び出しにコールバックを与えるので、Meteor は常にupdateへの呼び出しとのコールバックの間に何かをしようとしupdateます。ただし、Meteor 0.6.4.2 以前では、コールバックの使用に関係なく、データベースの更新は中断できませんでした。

ただし、複数の呼び出しsaveOnServerは順番に発生し、競合状態は発生しません。を呼び出しthis.unblock()て、複数の呼び出しを「同時に」発生させることができます。つまり、 とラベル付けされた、割り込み不可能なブロックのsaveOnServer同じキューを共有しないでください。saveOnServer queue

あなたが持っているコードを考えると、別のメソッドを変更すると、呼び出しと更新Collectionsの間の値が変更される可能性があります。count()

次のデータ モデルを実装することで、一方のメソッドが途中で他方を無効にするのを防ぐことができます。

saveOnServer : function () {
// ...
  Collections.update({_id:someId, initialized:true, collectionCount: {$gt: 0}},
    {$addToSet: {objects: object}});
///...
}

オブジェクトを に追加する場合Collections:

insertObject: function() {
//...
  var count = Collections.find({some: condition}).count();
  Collections.insert({_id:someId, initialized:false, collectionCount: count});
  Collections.update({initialized:false},
    {$set:{initialized:true}, $inc: {collectionCount: 1}});
}

これは非効率に見えるかもしれませんが、異なるメソッドでの更新と挿入を意図したとおりに動作させるための正確なコストを反映していることに注意してください。にsaveOnServerは挿入できません。

逆に、 からコールバックを削除すると、コールバックはCollections.update同期的に発生し、Meteor 0.6.5 以降では競合状態が発生しなくなります。

于 2013-08-08T06:01:13.803 に答える
1

このコレクションのインデックス フィールドに一意のキーを持たせ、次のように更新することができます。

1) コレクションに挿入するときは常に、最初にクエリを実行して最大インデックスを取得し、インデックス + 1 でドキュメントを挿入します。

2) ドキュメントの数を調べるには、クエリを実行してインデックスの最大値を取得します。

挿入は、読み取りと書き込みのクエリのペアになったため、失敗する可能性があります。(ただし、DB ops は常に失敗する可能性があります。) ただし、データベースを一貫性のない状態のままにすることはできません。Mongo インデックスはそれを保証します。

Meteor でインデックスを構築するための構文は次のとおりです。

MyCollection._ensureIndex('index', {unique: 1});
于 2013-08-12T07:40:47.230 に答える