问题描述
我对 Node.js 和 Mongo/Mongoose 还比较陌生,我非常很难排除特定的 Mongoose 错误:
I'm relatively new to Node.js and Mongo/Mongoose, and I'm having a very difficult time troubleshooting a specific Mongoose error:
版本错误:找不到匹配的文档.
(此问题底部的整个错误跟踪/堆栈.)
这篇博文非常清楚地概述了 VersionError 可能如何发生:
This blog post pretty clearly outline how a VersionError might occur:
(TL;DR - Mongoose v3 现在为每个文档添加了一个模式可配置的版本键.只要对数组的修改可能会改变任何数组的元素位置,这个值就会自动递增."如果你尝试保存一个文档,但版本密钥不再与您检索的对象匹配,您会得到上述 VersionError
.)
核心问题:有什么方法可以显示有问题的 save()
操作吗?或者哪个文件保存失败?或者什么?!;)
Core Question: Is there some way to display the offending save()
operation? Or which document failed to save? Or anything at all?! ;)
挑战:这是一个包含许多数组的相对较大的代码库,我不确定如何开始解决问题.特别是,错误跟踪/堆栈似乎没有显示问题存在的位置.见下文:
The Challenge: this is a relatively large code base with many arrays, and I am unsure how to begin to troubleshoot the problem. In particular, the error trace/stack does NOT seem to show where the problem exists. See below:
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)
推荐答案
根据请求,这里是我们问题的概述,以及我们如何解决它:
Per request, here is an outline of our problem, and how we resolved it:
在我们的系统中,我们创建了一个自定义文档锁定例程(使用 redis-lock),其中以这种精确(不正确)的顺序发生以下情况:
In our system we created a custom Document locking routine (using redis-lock), wherein the following happened in this precise (incorrect) order:
操作顺序不正确:
- 收到客户请求
- 文档已锁定
- 已检索文档
- 文档已编辑
- 文档已解锁
- 客户请求已解决
- 文档已保存
一旦你看到它写出来,问题就很明显了:我们将文档保存在文档锁之外.
Once you see it written out, the problem is obvious: we were saving our Documents outside our Document lock.
让我们假设 #6 在我们的系统中需要 100 毫秒.这是一个 100 毫秒的窗口,其中如果任何其他请求获取同一个文档,我们将发生保存冲突(恕我直言,此问题中的标题错误基本上是保存冲突).
Let's assume #6 takes 100ms in our system. That is a 100ms window wherein if any other requests grabs that same Document, we're going to have a save conflict (the titled error in this Question is basically a save conflict IMHO).
换句话说/示例:在我们的系统中,请求 A 抓取了文档 X 的版本 1,对其进行了编辑,然后将其解锁,但是在请求 A 保存文档之前,请求 B 抓取了文档 X 并将其增加到版本 2(阅读有关更多信息,请查看 Mongo 版本).然后请求 A 解决了它的客户端请求并去保存文档 X,但它试图保存版本 1,现在它看到它有版本 2,因此出现上述错误.
In other words/example: in our system, Request A grabbed Version 1 of Document X, edited it, then unlocked it, but before Request A saved the Document, Request B grabbed Document X and incremented it to Version 2 (read up on Mongo versions for more info about this). Then Request A resolves its Client request and goes to save Document X, but it's trying to save Version 1, and now it sees it has Version 2, and thus the error above.
所以修复很容易.将您的文档保存在您的锁中.(在上面的例子中,将#7 移到 #5 之前.见下文.)
So the fix is easy. Save your Documents inside your lock. (In the above example, move #7 to before #5. See below.)
正确/固定的操作顺序
- 收到客户请求
- 文档已锁定
- 已检索文档
- 文档已编辑
- 文档已保存
- 文档已解锁
- 客户请求已解决
(你可以提出 #6 和 #7 应该交换的论点,但这超出了 Mongo/Mongoose/这个问题的范围.)
(You could make an argument that #6 and #7 should be swapped, but that is outside the scope of Mongo/Mongoose/this question.)
我将暂时不回答这个问题,看看是否有人可以阐明一种更好的方法来隔离相关代码并解决此问题.在我们的案例中,这是一个非常系统性的问题,并且对于我们当时的技能水平来说非常具有挑战性.
I am going to leave this question un-answered for a while and see if anyone can shed some light on a better way to isolate the relevant code and troubleshoot this issue. In our case, this was a very systemic problem and VERY challenging to troubleshoot for our skill level at the time.
这篇关于“版本错误:找不到匹配的文档"Node.js/Mongoose 上的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!