KJW*_*KJW 7 javascript race-condition mongodb meteor
在我的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 {}
}
});
Run Code Online (Sandbox Code Playgroud)
我担心当2个客户端同时调用saveOnServer()时,它会为每个客户端返回相同的totalCount,并且最终会将相同的整数插入到对象id中.最终目标是在服务器端使用原子操作插入行,该操作仅在totalCount成功返回并且插入文档时完成,确保不存在重复的ID?我试图不使用mongodb _id,但有我自己的整数递增id列.
我想知道如何确保每个插入操作的字段自动递增?我目前依赖于获取文件总数.这里有竞争条件吗?如果是这样,处理这个问题的流星方式是什么?
在Meteor的并发模型中,您可以将整个方法想象为不间断的事件块.为了让Meteor从中途运行一个方法切换到开始另一个方法,你需要"屈服" - 方法需要发出信号,"我可以被打断".
方法在异步执行某些操作时会产生,实际上这意味着您在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}});
///...
}
Run Code Online (Sandbox Code Playgroud)
将对象添加到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}});
}
Run Code Online (Sandbox Code Playgroud)
请注意,虽然这可能看起来效率低下,但它反映了进行更新的确切成本,并且在不同方法中插入的行为与您的预期方式相同.在saveOnServer你不能插入.
相反,如果您从中删除了回调Collections.update,它将同步发生,并且没有竞争条件Meteor 0.6.5及更高版本.