node.js - Node.js/Mongoose 上的 "VersionError: No ma

我对 Node.js 和 Mongo/Mongoose 比较陌生,我在排除特定的 Mongoose 错误时遇到了非常困难:

版本错误:找不到匹配的文档。

(此问题底部的整个错误跟踪/堆栈。)

这篇博文非常清楚地概述了 VersionError 是如何发生的:

  • http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html

(TL;DR - “Mongoose v3 现在为每个文档添加了一个模式可配置的版本键。只要对数组的修改可能会更改任何数组的元素位置,这个值就会自动递增。”如果您尝试保存一个文档,但是版本键不再匹配你检索到的对象,你得到上面的 VersionError。)

核心问题:有没有办法显示有问题的 save() 操作?或者哪个文件保存失败?还是任何东西?! ;)

挑战:这是一个包含许多数组的相对较大的代码库,我不确定如何开始解决问题。特别是,错误跟踪/堆栈似乎没有显示问题存在的位置。见下文:

VersionError: No matching document found.
at handleSave (<project_path>/node_modules/mongoose/lib/model.js:121:23)
at exports.tick (<project_path>/node_modules/mongoose/lib/utils.js:408:16)
at null.<anonymous> (<project_path>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/collection.js:484:9)
at g (events.js:192:14)
at EventEmitter.emit (events.js:126:20)
at Server.Base._callHandler (<project_path>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:391:25)
at Server.connect.connectionPool.on.server._serverState (<project_path>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:558:20)
at MongoReply.parseBody (<project_path>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:131:5)
at Server.connect.connectionPool.on.server._serverState (<project_path>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:517:22)
at EventEmitter.emit (events.js:96:17)

最佳答案

根据要求,以下是我们问题的概述,以及我们如何解决它:

在我们的系统中,我们创建了一个自定义文档锁定例程(使用 redis-lock),其中以这种精确(不正确)的顺序发生了以下情况:

操作顺序不正确:

  1. 收到客户请求
  2. 文档锁定
  3. 检索到的文档
  4. 文档已编辑
  5. 文件已解锁
  6. 客户请求已解决
  7. 文件已保存

一旦你看到它被写出来,问题就很明显了:我们将文档保存在文档锁之外。

假设#6 在我们的系统中需要 100 毫秒。那是一个 100 毫秒的窗口,如果任何其他请求获取相同的文档,我们将发生保存冲突(这个问题中的标题错误基本上是保存冲突恕我直言)。

换句话说/示例:在我们的系统中,请求 A 抓取了文档 X 的版本 1,对其进行了编辑,然后将其解锁,但在请求 A 保存文档之前,请求 B 抓取了文档 X 并将其增加到版本 2(阅读在 Mongo 版本上了解有关此的更多信息)。然后请求 A 解析其客户端请求并保存文档 X,但它正在尝试保存版本 1,现在它看到它具有版本 2,因此出现上述错误。

所以修复很容易。将您的文件保存在您的锁内。 (在上面的例子中,将#7 移到#5 之前。见下文。)

正确/固定的操作顺序

  1. 收到客户请求
  2. 文档锁定
  3. 检索到的文档
  4. 文档已编辑
  5. 文件已保存
  6. 文件已解锁
  7. 客户请求已解决

(您可以提出应该交换 #6 和 #7 的论点,但这超出了 Mongo/Mongoose/this question 的范围。)

我将暂时不回答这个问题,看看是否有人可以阐明一种更好的方法来隔离相关代码并解决此问题。在我们的案例中,这是一个非常系统性的问题,并且对于我们当时的技能水平进行故障排除非常具有挑战性。

关于node.js - Node.js/Mongoose 上的 "VersionError: No matching document found"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17499089/

相关文章:

mongodb - 只安装 mongo shell,不安装 mongodb

javascript - 在 Meteor 应用程序中实现 MongoDB 2.4 的全文搜索

node.js - Mongoose 试图打开未关闭的连接

mongodb - 自动重新连接异常 "master has changed"

mongodb - 尝试连接到 mongodb 服务器时无法识别 mongo 命令

c# - 使用官方 C# 驱动程序在 Mongo DB 中进行更新插入

javascript - MongoDB - 更新集合中所有记录的最快方法是什么?

node.js - Mongoose 密码哈希

c# - 如何使用 MongoDB 的 C# 驱动程序指定 Order 或 Sort?

mongodb - 相当于 MongoDB 的 ERD?