Mongoengine - 我可以从两个后续查询中获取相同的文档对象实例吗?

问题描述

这是用例:我有一个服务器,它接收来自许多客户端的指令。每个客户端指令都由其自己的 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...