流星:服务器端的Meteor.collections是否可能发生竞争状况? [英] Meteor: Could a race condition happen with Meteor.collections on server side?

查看:75
本文介绍了流星:服务器端的Meteor.collections是否可能发生竞争状况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的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 {}
    }
});

恐怕当2个客户端同时调用saveOnServer()时,它将为每个客户端返回相同的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(),以允许"c4"同时发生多次调用,即,不共享不间断块中相同的队列,标记为saveOnServer queue.

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中删除了回调,它将同步发生,并且不会出现流星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.collections是否可能发生竞争状况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆