问题描述
这是用例:我有一个服务器,它接收来自许多客户端的指令。每个客户端指令都由其自己的 Session 对象处理,该对象保存有关会话状态的所有信息,并向 mongoengine 查询所需的数据。
现在,假设 session1 查询 mongoengine 并获取文档“A”作为文档对象。
稍后,session2 也查询并获取文档“A”,作为另一个单独的文档对象。
现在我们有 2 个表示文档“A”的文档对象,为了让它们保持一致,我需要一直调用 A.update() 和 A.reload(),这似乎没有必要。
有什么办法可以通过两个查询获得对同一个文档对象的引用?这样,两个会话都可以对文档对象进行更改,而这些更改将被其他会话看到,因为它们将更改为同一个 Python 对象。
我曾考虑为 mongoengine 制作一个包装器,它可以在运行时缓存我们作为文档对象的文档,并确保在任何给定时间都没有同一文档的多个对象。但当时我对 mongoengine 的了解太初级,无法做到。
对此有什么想法吗?我的整个设计有缺陷吗?有什么简单的办法吗?
解决方法
我不认为朝那个方向发展是个好主意。据我了解,您处于 Web 应用程序上下文中,您可能能够在单个进程中为线程工作,但您将无法在不同进程之间共享实例(如果有进程正在运行,情况会变得更糟在不同的机器上)。
解决这个问题的一种方法是使用乐观并发验证,你基本上维护一个像“版本标识符”这样的字段,只要实例更新,只要你保存/更新对象,你就会运行一个像“更新”这样的查询object if version-identifier=...否则你失败"
这意味着如果有并发请求,其中 1 个会成功(第一个被刷新),另一个会失败,因为它们拥有的版本标识符已过时。 MongoEngine 没有内置支持,但可以在此处找到更多信息 https://github.com/MongoEngine/mongoengine/issues/1563