NodeJS, ExpressJS, Mongoose 4.4, Nonce for concurrency and D



我有以下组合,NodeJS,Express,MongoDB和Mongoose。我已经实现了带有猫鼬承诺的随机数,以允许并发编辑。请参阅以下内容:

//schema
var item_schema = {
    //_id: {type: Schema.ObjectId, required: true},
    name: {type: String, required: true, index: { unique: true }},
    code: {type: String, required: true, index: { unique: true }},
    date_time_created: {type: Date, required: true},
    date_time_updated: {type: Date, required: true},
    nonce: {type: Schema.ObjectId}
};
//model
var item_model = mongoose.model('item', schema);
//update
var concurrency_update = function(req, res, retries) {
    var promise = model.findById(req.params.id).exec();
    var updated_nonce = mongoose.Types.ObjectId();
    promise.then(function(document){ //find document response
        if(!document) {
            res.status = 404;
            return Promise.reject( { "message" : req.params.id + ' document does not exist' } );
        }
        var now = new Date();
        if(req.body.code) {
            document.code = req.body.code;
            document.date_time_updated = now;
        }
        if(req.body.name) {
            document.name = req.body.name;
            document.date_time_updated = now;
        }
        if(!document.nonce) {
            document.nonce = updated_nonce;
            var old_nonce = document.nonce;
        }
        else {
            var old_nonce = document.nonce;
            document.nonce = updated_nonce;
        }
        return document.update({ "_id" : req.params.id, "nonce" : old_nonce }).exec();
    }).then(function(raw){ //update response
        var number_affected = raw.n;
        console.log(raw);
        if(!number_affected && retries < 10){
            //we weren't able to update the doc because someone else modified it first, retry
            console.log("Unable to update, retrying ", retries);
            //retry with a little delay
            setTimeout(function(){
                concurrency_update(req, res, (retries + 1));
            }, 20);
        } else if (retries >= 10){
            //there is probably something wrong, just return an error
            return Promise.reject({ "message" : "Couldn't update document after 10 retries in update"});
        } else {
            res.json({"message": req.params.id + ' document was update'});
        }
    }).catch(function(err){
        res.send(err.message);
    });

并发更新基于以下内容:http://www.mattpalmerlee.com/2014/03/22/a-pattern-for-handling-concurrent/

阅读猫鼬文档,更新基于此。http://mongoosejs.com/docs/api.html#document_Document-update

但是,当代码进入最终的 .then(//update 响应)时,我看到 raw.n (numberAffected ) = 1,但数据库从未更新?

答案可能接近,但我错过了。我错过了什么?

在 @blakes_seven 发表评论后,我能够删除随机数的使用并使用原子修饰符应用更新。这是更新的测试代码。

//schema
var item_schema = {
    //_id: {type: Schema.ObjectId, required: true},
    name: {type: String, required: true, index: { unique: true }},
    code: {type: String, required: true, index: { unique: true }},
    date_time_created: {type: Date, required: true},
    date_time_updated: {type: Date, required: true},
    nonce: {type: Schema.ObjectId}
};
//model
var item_model = mongoose.model('item', schema);
//update
var concurrency_update = function(req, res, retries) {
    var updated_data = {};
    if(req.body.code) {
        updated_data.code = req.body.code;
    }
    if(req.body.name) {
        updated_data.name = req.body.name;
    }
    if(!req.body.name.nonce) {
        updated_data.nonce = mongoose.Types.ObjectId();
    }
    if(updated_data !== {}) {
        var update = {
            $currentDate: {
                date_time_updated: true
            },
            $set: updated_data
        };
        var promise = model.update({"_id": req.params.id}, update).exec();
        promise.then(function (raw) {
            var number_affected = raw.nModified;
            console.log(raw);
            if (!number_affected && retries < 10) {
                //we weren't able to update the doc because someone else modified it first, retry
                console.log("Unable to update, retrying ", retries);
                //retry with a little delay
                setTimeout(function () {
                    concurrency_update(req, res, (retries + 1));
                }, 20);
            } else if (retries >= 10) {
                //there is probably something wrong, just return an error
                return Promise.reject({"message": "Couldn't update document after 10 retries in update"});
            } else {
                res.json({"message": req.params.id + ' document was update'});
            }
        }).catch(function (err) {
            res.send(err.message);
        });
    }
    else {
        res.status = 400;
        res.send({"message": 'There is nothing specified in the payload to update!'})
    }
};

最新更新