Mongooseasynchronous多重保存冲突

我有一个大的逻辑问题,使用Node / Mongoose / Socket.io …假设我有一个服务器模型,通常在我的应用程序中同时调用,一些调用涉及更新模型中的数据。

db.Server.findOne({_id: reference.server}).exec(function(error, server) { catches.error(error); if (server !== null) { server.anything = "ahah"; server.save(function(error) { }); } } 

有时候,有两个人同时打电话给这个人,而第一个人会保存()另一个人已经可以find一个“服务器”,并得到不是最新的“旧对象” )它。

这里最大的问题就是当第二个人将“服务器”(“旧对象”)保存起来时,它会直接覆盖第一个的变化……你可以想象它会在我的应用程序上产生巨大的冲突。

我想把所有的save()方法改成update(),这样可以摆脱这个问题,但是在项目中的某个时刻,直接使用update()是非常困难的,而不是那么实用。

有人在更新它时“locking”findOne()调用吗? 就像你find一个(),你也会说:“嘿,我会尽快更新,所以不要让人们现在find它”(与mongoose,甚至MongoDb)

这是一段时间,我正在寻找我没有find任何答案:(

希望你明白我的问题;)谢谢你!

正如您在这里可以告诉的,这不是处理数据处理更新的最佳方式。 如果你考虑你要做的事情,基本上可以归结为:

  1. 从数据库中获取对象。
  2. 更新代码中的属性。
  3. 保存该数据,不保证其他内容修改。

因此,在可能的情况下,您需要避免使用这种模式,并遵循您只需更改现有值的常识,而现在的值不能设置为该值。 所以这意味着只需要使用$set这样的操作符来处理“update”types的语句:

 db.Server.findOneAndUpdate( { "_id": refernce.server, "anything": { "$ne": "ahah" } }, { "$set": { "anything": "ahah" } }, function(err,server) { if ( server != null ) { // then something was actually found and modified // so server now is the updated document } } ); 

这意味着你将任何字段validation或其他保存钩子的mongoose扔掉,但它是一个“primefaces”forms的更新,读写不是单独的操作,这是你目前正在实施。

如果你正在寻求实施某种types的“locking”,那么采用类似的方法是最好的方法。 因此,如果您想在文档上设置“状态”以显示某人正在编辑该文档,请维护一个字段,并将其构build到您的查询中。

对于“阅读”一个文件,并获得你想要呈现给“编辑”的信息,那么你会做这样的事情:

 db.Server.findOneAndUpdate( { "$_id": docId, "locked": false }, { "$set": { "locked": true } }, function(err,document) { } ); 

这意味着当某人“抓住”编辑时,后续的操作将无法执行,因为他们正在寻找检索locking状态为false的文档,而不再是这样。 将编辑提交为“保存”时也适用相同的原则,正好相反:

 db.Server.findOneAndUpdate( { "$_id": docId, "locked": true }, { "$set": { "locked": false } }, function(err,document) { } ); 

您始终可以执行更高级的操作,例如保存的修订版本,或者期望版本号包含操作或任何其他forms的处理。 但总的来说,你应该根据自己的需要自己pipe理这个

我刚刚意识到我发布了一个类似的post堆栈溢出。 你可以在这里find这个post: 如何用mongoDB / mongoose并行执行读/写文件

在这篇文章中,有人告诉我在内存中保留一些东西来避免这种行为。 这是我做的,它很好。 但是,如果您正在使用多进程,则需要find在进程之间共享内存的方法。