如何以原子方式获取最新的“回合”记录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');
});
});
答案 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次更新,而是查找+插入)。