Mongoose异步多保存冲突
Mongoose asynchronous multiple save conflicts
我在使用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) { });
}
}
有时,两个人会同时调用这个,而第一个人会保存(),另一个人可能已经找到了"服务器"findOne,并得到了不是最新的"旧对象"并保存()。
这里的大问题是,当第二个人保存()"服务器"("旧对象")时,它会覆盖第一个的更改。。。你可以想象它会在我的应用程序上产生多大的冲突。
我曾想过将所有的save()方法改为update(),这样就可以解决这个问题,但在项目的某个阶段,直接使用update()非常棘手,而且不太实用。
有没有一种方法可以在有人更新findOne()调用时"锁定"它?就像当你找到One()时,你也会说"嘿,我很快就会更新这个,所以现在不要让人们找到它"(使用Mongoose,甚至MongoDb)
我已经搜索了一段时间,没有找到任何答案:(
希望你能理解我的问题;)非常感谢。
正如您在这里看到的,这不是处理数据更新的最佳方式。如果你考虑你要求做什么,基本上可以归结为:
- 从数据库中获取对象
- 更新代码中的属性
- 将数据保存回,而不保证会有其他东西对其进行修改
因此,在可能的情况下,您需要避免这种模式,并遵循常识,即您只需要更改当前未设置为该值的现有值。因此,这意味着只需使用运算符处理"更新"类型的语句,如$set
:
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
}
}
);
这意味着您将放弃mongoose的任何字段验证或其他保存挂钩,但这是一种"原子"形式的更新,因为读取和写入不是单独的操作,这就是您当前实现的方式。
如果你想实现某种类型的"锁定",那么类似的方法是最好的方法。因此,如果你想在文档上设置一个"状态"来显示有人正在编辑它,那么就维护一个字段来进行编辑,并将其构建到你的查询中。
为了"阅读"一份文件并获得你想呈现给"编辑"的信息,你可以做这样的事情:
db.Server.findOneAndUpdate(
{ "$_id": docId, "locked": false },
{ "$set": { "locked": true } },
function(err,document) {
}
);
这意味着当有人"抓取"编辑时,随后的操作将无法做到这一点,因为他们希望检索锁定状态为false
的文档,而现在已经不是了。当将编辑提交为"保存"时,同样的原则也适用,只是相反:
db.Server.findOneAndUpdate(
{ "$_id": docId, "locked": true },
{ "$set": { "locked": false } },
function(err,document) {
}
);
您总是可以执行更高级的操作,例如保存的修订,或期望通过操作或任何其他形式的处理获得版本号。但一般来说,您应该根据自己的需求自行管理
我刚刚意识到我发布了一篇关于堆栈溢出的类似帖子。你可以在这里找到帖子:如何使用mongoDB/mongoose 在并行执行中读取/写入文档
在这篇帖子中,有人告诉我要记住一些日期,以避免这种行为。这就是我所做的,而且效果很好。但是,如果您使用多进程,则需要找到一种在进程之间共享内存的方法。
- 如何将getJson的响应保存在全局变量中
- 按下按钮时保存cookie
- 如何使用 Angular JS 将数据保存在数据库中
- 子字符串/正则表达式以获取字符串中保存的 SRC 值
- HTML5在画布中加载较小的图像并保存实际大小的图像
- 是否可以在浏览器中使用纯JavaScript保存音频流
- 如何将多个画布保存为一个图像
- PHP:显示sqlite数据库中的html格式数据,使用tinymce保存
- Javascript-ID冲突的几率
- 如何将乳胶配方奶粉图像保存到Asp.net中的文件夹中
- 保存数组javascript
- 保存串行端口列表与流星
- 将JavaScript变量保存到Rails模型
- Java脚本将URL转换为已保存的URL时出错
- 如何自动保存动态生成的HTML SVG元素
- Javascript/jQuery压缩一个图像正确的评论帖子,并使用Ajax Laravel 5.2保存到控制器中
- 将JQuery Handontable保存到服务器上的excel文件中
- SharePoint 2013 更新列表项时保存冲突错误
- Mongoose异步多保存冲突
- 上传附件时,保存冲突错误