使用mongoose的交易行为

时间:2014-05-07 17:49:07

标签: arrays node.js mongodb concurrency mongoose

假设我在mongoose中有一个架构A。它看起来像这样:

{
    arr: [{
        num: Number,
        text: String
    }]
}

现在我想执行以下操作:

  1. 选择Aa

  2. 获取a.arr项目的实际数量。

  3. 使用计数和文本向a.arr添加新元素。

  4. 我的实施:

    A.findOne({_id: someId}, function(err, a) {
        var count = a.arr.length;
        a.push({
            count: count,
            text: 'some text'
        });
        a.save(...)
    });
    

    到目前为止工作正常。 但是我的问题: 如果我执行该并发,假设有5个进程,某些进程在其他进程保存之前执行findOne。 因此前几个计数为0,然后当它们保存时,它会立即获得3或4个进程。

    但我想要执行串行。

    如何实现?

    谢谢!

1 个答案:

答案 0 :(得分:2)

mongo中没有事务支持,但你可以实现两个阶段提交,如http://cookbook.mongodb.org/patterns/perform-two-phase-commits/

中所述

或者,您可以在进程之间实现某些协调,如果数据支持此方案,则fx将数据范围分配给特定进程。

编辑以非常简单的形式,您可以通过添加属性lockProcessId并使用以下命令序列来实现一些乐观文档锁定:

db.A.findAndModify({_id: someId, lockProcessId:{$exists:false}},{$set:{lockProcessId: someProcessId},{new:true}}

db.A.findAndModify({_id: someId, lockProcessId:someProcessId},{$push:{arr:{ count: count,text:'some text'}},$unset:{lockProcessId:1}})

如果第一个查询没有返回任何内容,则进程应跳过此文档,否则应运行第二个查询

但是,如果某些进程在中间死亡,您可能会锁定某些文档,可能需要一些调度程序来清除锁定状态。