我正在开发一个具有类似下面代码的例程的应用程序:
//The model in question is used as a bugtracker, where all caught errors
//are collected together inside a bug-object with a unique code to track
//which function threw it
createOrUpdateBug: function(functionIdentifier, thrownError) {
return new Promise(function(resolve, reject) {
Promise.try(function() {
return model.findOne({bugCode: functionIdentifier})
}.then(function(foundModel) {
if (foundModel) {
foundModel.errors.push(thrownError)
return foundModel.save()
} else {
var newModel = new Model()
newModel.errors.push(thrownError)
return newModel.save()
}
}.then(function(savedModel) {
resolve(savedModel)
}) //.catch with reject omitted
})
}
我已经阅读了MongoDB,它似乎不符合ACID,或者至少不是更新和保存多个文档。据我所知,这意味着当2个文档受到某个操作的影响,并且它们都是异步保存时,由于可能的服务器异常,它们在某些时候会相互不一致。这有点正确吗?
在我的情况下,我想保证每个functionIdentifier只有1个文档。但是,如果同时运行此函数,是否有可能生成具有相同functionIdentifier的多个文档?
[1]看模型是否存在 - > [2]看模型是否存在 - > [1]没有发现模型 - > [2]未找到模型 - > [1]创建模型 - > [2]创建模型 - > [1]保存模型 - > [2]保存模型
我可以在数据库中将functionIdentifier标记为唯一,但是当违反验证时,我不会丢失第二个进程的信息吗?
MongoDB应该在文档级别上符合ACID,但我不确定这是否可以保护我的实现。或者是吗?
答案 0 :(得分:0)
您最想要的是upsert
,它会根据文档是否存在来插入或更新文档:
// Push an error to bugcode 1
db.model.update({bugCode:1}, {$push: {'errors' : 'error 1'}}, {upsert:1})
// Push an error to bugcode 1
db.model.update({bugCode:1}, {$push: {'errors' : 'error 2'}}, {upsert:1})
// Push an error to bugcode 2
db.model.update({bugCode:2}, {$push: {'errors' : 'error 3'}}, {upsert:1})
db.model.find()
// { "_id" : ObjectId("56c88be6604725e791ffd967"),
// "bugCode" : 1, "errors" : [ "error 1", "error 2" ] } // Two errors
// { "_id" : ObjectId("56c88c09fc04922eb90fcc61"),
// "bugCode" : 2, "errors" : [ "error 3" ] } // One error
答案 1 :(得分:0)
MongoDB应该在文档级别上符合ACID,但我不确定这是否可以保护我的实现。或者是吗?
在你自己陈述的情景中并没有。但是,如果您的functionIdentifier是唯一的,您可以将其设置为_id
字段,它将触发自动"如果存在,则更新,否则插入"来自save
的行为。