假设我在 Mongoose 中有一个模式A
。它看起来像这样:
{
arr: [{
num: Number,
text: String
}]
}
现在我要执行以下操作:
选择一个
A
,即a
。获取
a.arr
的项目的实际数量。向
a.arr
添加一个新元素,其中包含计数和文本。
我的实现:
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。
但我希望它能够串行执行。
如何实现这一目标?
谢谢!
最佳答案
mongo 中没有事务支持,但您可以实现两阶段提交,如 http://cookbook.mongodb.org/patterns/perform-two-phase-commits/ 中所述。
或者,您可以在进程之间实现一些协调,如果数据支持此场景,则将数据范围分配给特定进程。
编辑:以非常简单的形式,您可以通过添加属性 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}})
如果第一个查询没有返回任何内容,则进程应跳过此文档,否则应运行第二个查询
但是,如果某个进程在中间终止,您可能会锁定一些文档,可能您需要一些调度程序来清除锁定状态。
关于arrays - Mongoose 的事务行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23524726/