MongoDB:对2个集合进行原子调用(查找+插入)

时间:2015-10-15 18:55:51

标签: node.js mongodb atomic nosql

如何以原子方式获取最新的“回合”记录ObjectId并在插入“deposit”集合时使用它?

这篇帖子答案说无法完成:Is there any way to atomically update two collections in MongoDB? 这仍然是真的吗?

在过程A中,我想原子地查找最新的圆形id(rid)并将其插入存款中。竞争条件是在A找到摆脱之后,另一个进程B可能会插入轮次,所以现在A有一个不是最新的摆脱,但是落后了1。 A怎么能找到轮次+将这个rid插入存款(对这2个集合起作用)原子?

    // GET ROUND ID (RID) OF LATEST

    var rid;
    db.rounds.find().limit(1).sort({$natural:-1}, function(err, latestInsertedRound){
        rid = latestInsertedRound[0]._id;
        print(rid, 'rid'); // if another process B inserts now, this rid is 1 behind

        // INSERT INTO DEPOSITS

        db.deposits.insert({uid:uid, iid:iid, rid:rid}, function(err, insertedDeposit){
             print(insertedDeposit, 'insertedDeposit');
        });
    });

2 个答案:

答案 0 :(得分:1)

在Mongodb中插入文档有一个可以使用的回调函数。此回调函数具有第二个参数,该参数返回插入的文档。

我尝试使用console.log打印第二个参数。它看起来像:

{ result: { ok: 1, n: 1 },
ops:
    [ { username: 'user1',
        password: 'password1',
        _id: 562099bae1872f58b3a22aed } ],
    insertedCount: 1,
    insertedIds: [ 562099bae1872f58b3a22aed ]
}

insertedIds是包含所插入文档或文档的_ids的数组。

因此,您可以在插入第一个集合的函数回调中将对象插入第二个集合中。有点混乱。

简单来说:将文档插入第一个集合中。在它的回调中,将文档插入第二个集合中。

MongoClient.connect(MONGOLAB_URI, function (err, db) {
    if (err)
        console.log("We have some error : " + err);

    else {            
        db.createCollection('rounds', function (err, rounds) {
            if (err) {
                console.log('Error while creating rounds collection');
                throw err;
            }

            else {
                rounds.insert({ 'username' : 'user1', 'password' : 'password1' }, function(err,docsInserted){
                    console.log('Last document inserted id :', docsInserted.insertedIds[0]);

                    //inserting the document in the function callback
                    db.createCollection('deposits', function (err, deposits) {
                        if (err) {
                            console.log('Error while creating deposits collection');
                            throw err;
                        }

                        else {
                            //change array index according to your need
                            //you may be inserting multiple objects simultaneously
                            deposits.insert({'last_inserted_object' : docsInserted.insertedIds[0]);

                            console.log('inserted into deposits collection');
                        }
                    });
                });
            }
        });
    }
});

答案 1 :(得分:0)

似乎不可能在MongoDB中的2个集合上进行原子操作,如本答案所述:

Is there any way to atomically update two collections in MongoDB?

我保留这个问题,因为它的焦点略有不同(不是2次更新,而是查找+插入)。