根据请求,以下是我们的问题及其解决方案的概述:
在我们的系统中,我们创建了一个自定义文档锁定例程(使用redis-lock),其中以下操作以这种精确(不正确)的顺序发生:
操作顺序不正确:
- 收到客户要求
- 文件已锁定
- 检索文件
- 文件已编辑
- 文件已解锁
- 客户要求已解决
- 文件已储存
一旦看到它写出来,问题就很明显了:我们将文档保存在文档锁之外。
假设#6在我们的系统中花费了100ms。这是一个100毫秒的窗口,如果任何其他请求都抓住了该文档,我们将发生保存冲突(此问题中的标题错误基本上是保存冲突恕我直言)。
换句话说,在我们的系统中,请求A抓取了文档X的版本1,对其进行了编辑,然后将其解锁,但是在请求A保存该文档之前,请求B抓取了文档X并将其递增到版本2(在Mongo上阅读)有关更多信息的版本)。然后,请求A解析其客户请求并保存文档X,但它正在尝试保存版本1,现在它看到它具有版本2,因此出现上述错误。
因此修复很容易。将文档保存在锁中。(在上面的示例中,将#7移至#5之前。请参见下文。)
正确/固定的操作顺序
- 收到客户要求
- 文件已锁定
- 检索文件
- 文件已编辑
- 文件已储存
- 文件已解锁
- 客户要求已解决
(您可以争辩说应该交换#6和#7,但这不在Mongo / Mongoose /这个问题的范围内。)
我将暂时搁置这个问题,看看是否有人可以找到更好的方法来隔离相关代码并解决此问题。在我们的案例中,这是一个非常系统的问题,非常难以解决当时的技术水平。



