Python 谷歌应用引擎数据存储:处理最终一致性 我正在开发一个GAE Web应用程序,并且我需要创建和删除两个没有祖先关系的实体的实例之间的关联(也考虑到同一个实例可能有多个关联,这些关联可能随时间而变化,而祖先关系,一旦创建,就不能被移除)。 我经历过“最终一致性”策略,这意味着我的网页中的数据不能与我正在创建/删除的关系一致地刷新。 然而,我已经看到,通过两次执行put()方法,一致性似乎是强制的

Python 谷歌应用引擎数据存储:处理最终一致性 我正在开发一个GAE Web应用程序,并且我需要创建和删除两个没有祖先关系的实体的实例之间的关联(也考虑到同一个实例可能有多个关联,这些关联可能随时间而变化,而祖先关系,一旦创建,就不能被移除)。 我经历过“最终一致性”策略,这意味着我的网页中的数据不能与我正在创建/删除的关系一致地刷新。 然而,我已经看到,通过两次执行put()方法,一致性似乎是强制的,python,google-app-engine,google-cloud-datastore,Python,Google App Engine,Google Cloud Datastore,这符合“最终一致性”的定义,该定义规定“……如果不进行新的更新……”数据最终将是一致的,并且,由于我正在进行另一次更新(实际上是相同的两次),我猜系统强制保持一致性 我说得对吗?还有其他更优雅的方式吗 更新:我的目标 假设我有一个a型实体的列表,它们实际上代表什么并不重要,假设它们代表我业务的主要实体 我有一个B型实体的列表,表示a型实体可以依赖的服务。 这是一种多对多的关系 服务b可由A类型的许多实体A使用 一个实体a可以由许多类型b的服务b提供服务 我有一个网页,允许我创建这样的关系(一个J

这符合“最终一致性”的定义,该定义规定“……如果不进行新的更新……”数据最终将是一致的,并且,由于我正在进行另一次更新(实际上是相同的两次),我猜系统强制保持一致性

我说得对吗?还有其他更优雅的方式吗

更新:我的目标

假设我有一个a型实体的列表,它们实际上代表什么并不重要,假设它们代表我业务的主要实体 我有一个B型实体的列表,表示a型实体可以依赖的服务。 这是一种多对多的关系 服务b可由A类型的许多实体A使用 一个实体a可以由许多类型b的服务b提供服务

我有一个网页,允许我创建这样的关系(一个Jinja2模板,具有来自客户端的jQueryAjax回调和依赖于服务器端数据存储的WebApp2Python请求处理程序)。 当从数据存储中删除一个关系时,我通过对a实体进行另一次查询并描述它相关的b键列表来刷新数据。在这种情况下,我仍然可以在与a相关的b键列表中看到已删除的b键。这不是我所期望的

更新:一些代码

这是模型

class A(ndb.Model):
    name = ndb.StringProperty()
    services = ndb.KeyProperty(repeated=True)

class B(ndb.Model):
    name = ndb.StringProperty()
    servedEntities = ndb.KeyProperty(repeated=True)
下面是我用来创建关系的代码

                a.services.append(b.key);
                b.servedEntities.append(a.key);
                a.put()
                b.put()
               a.services.remove(b.key);
               b.servedEntities.remove(a.key);
               a.put()
               b.put()
下面是我用来删除关系的代码

                a.services.append(b.key);
                b.servedEntities.append(a.key);
                a.put()
                b.put()
               a.services.remove(b.key);
               b.servedEntities.remove(a.key);
               a.put()
               b.put()
a和b之间没有祖先关系(也不可能有)
删除关系后,如果再次从数据存储中检索a,我仍然可以看到a.services中列出的b.key。您的问题的答案如下:

当从数据存储中删除关系时,我会刷新数据 通过对实体的属性进行另一个查询

为什么需要新的查询

假设一个用户订阅了服务x、y和z。现在,用户告诉您从列表中删除服务z。您可以转到数据存储并进行必要的更改。但是,不必运行新的查询(可能仍然在返回的实体中显示z),您只需从客户端的用户实体中删除z并相应地更新UI即可


这显然是一个简化的例子。我在编写school scheduling应用程序时遇到了类似的挑战,该应用程序有一个更复杂的用例——在选定的时间段内,一次更改可能会影响到许多实体(例如,“在本季度结束之前,每天安排一节课”),因此我试图简单地运行一个新查询来刷新schedule视图。显然,我遇到了最终的一致性问题,这一问题由于有时必须创建几十个实体而被放大。然后我意识到我已经拥有了刷新视图所需的所有数据,而无需运行新的查询。它的代码要多一点,但它是一个干净可靠的解决方案。

你不能通过做两次put来强迫它,它是无用的。你能描述一下为什么你需要它们保持一致吗?更新了,我希望我已经清楚了,如果你能包含尽可能少的代码样本,这代表了问题——会更容易帮助你。更新了一些代码它只有在你做查询时才可见,对吗?如果您将在此处列出的sot中尝试
a.key.get()
--
b
?可以,但如果用户刷新页面,他会看到旧项目重新出现,而不考虑用户手指的速度和网络延迟,除非用户在点击保存按钮的毫秒内设法点击刷新按钮,否则刷新的页面将被正确更新。这种情况多久发生一次?考虑到这种可能性,是否要将写入成本翻倍?(根据我的经验,即使涉及多个实体,最终的一致性也很少需要超过一秒钟的时间来解决)。@lowcoupling因为这是一个ajax-y应用程序,刷新就不太常见了。您还可以[利用memcache][1]将这种情况降至最低。但是,最后,如果您需要这种一致性,您可以选择1)重新构造模式以使用实体组或数据存储的其他强一致性功能,或者2)不使用app engine。