问题描述
在我的 server/server.js 中
in my 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 列.
I'm afraid that when saveOnServer() is called by 2 clients at the same time, it will return the same totalCount for each client and basically end up inserting same integer number into object id. The end goal is to insert row on the server side with an atomic operation that only completes when the totalCount
is successfully returned and the document is inserted ensuring that no duplicate id exists? I'm trying to not use the mongodb _id but have my own integer incrementing id column.
我想知道如何确保字段为每个插入操作自动递增?我目前依赖于获取文件总数.这里可能存在竞争条件吗?如果是这样,流星的处理方式是什么?
I'm wondering how I can ensure that a field gets auto-incremented for each insert operation? I am currently relying on getting the total count of documents. Is a race condition possible here? If so, what is the meteor way of dealing with this?
推荐答案
在 Meteor 的并发模型中,您可以将整个方法想象为发生的不可中断的事情块.为了让 Meteor 从运行一种方法中途切换到开始另一种方法,你需要让步"——该方法需要发出信号,我可以被打断."
In Meteor's concurrency model, you can imagine a whole method as an uninterruptible block of stuff that happens. In order for Meteor to switch from running one method midway to say, starting another method, you need to "yield"—the method needs to signal, "I can be interrupted."
方法在执行异步操作时会产生收益,这实际上意味着在 Meteor 0.6.5 及更高版本中进行数据库更新或调用具有回调的方法时.由于您给 update
调用一个回调,Meteor 将总是尝试在调用 update
和 update 的回调.但是,在 Meteor 0.6.4.2 及更早版本中,无论使用回调如何,数据库更新都是不间断的.
Methods yield whenever they do something asynchronous, which in practice means any time you do a database update or call a method with a callback in Meteor 0.6.5 and later. Since you give your
update
call a callback, Meteor will always try to do something in between the call to update
and the update
's callback. However, in Meteor 0.6.4.2 and earlier, database updates were uninterruptible regardless of the use of callbacks.
但是,对
saveOnServer
的多次调用将按顺序发生并且不会导致竞争条件.您可以调用 this.unblock()
以允许对 saveOnServer
的多次调用同时"发生——即,不共享同一队列,标记为 saveOnServer 队列,不间断的东西块.
However, multiple calls to
saveOnServer
will happen in order and do not cause a race condition. You can call this.unblock()
to allow multiple calls to saveOnServer
to occur "simultaneously"—i.e., not share the same queue, labeled saveOnServer queue
, of uninterruptible blocks of stuff.
给定您拥有的代码,另一种修改
Collections
的方法可以在调用和更新之间更改 count()
的值.
Given the code you have, another method modifying
Collections
can change the value of count()
between the call and the update.
您可以通过实现以下数据模型来防止一种方法中途使另一种无效:
You can prevent one method from making the other invalid midway by implementing the following data models:
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
中不能插入.
Note, while this may seem inefficient, it reflects the exact cost of making an update and insert in different methods behave the way you intend. In
saveOnServer
you cannot insert.
相反,如果您从
Collections.update
中删除回调,它将同步发生,并且不会有竞争条件 Meteor 0.6.5 及更高版本.
Conversely, if you removed the callback from
Collections.update
, it will occur synchronously and there will be no race conditioning Meteor 0.6.5 and later.
这篇关于Meteor:服务器端的 Meteor.collections 会发生竞争条件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!