Google App Engine数据存储区:处理最终的一致性

时间:2014-12-24 08:27:40

标签: python google-app-engine google-cloud-datastore

我正在开发一个GAE Web应用程序,我需要在两个没有祖先关系的实体的实例之间创建和删除关联(也考虑同一个实例可能有多个关联,这些关联可能会在祖先关系创建时发生变化,一旦创建,不能被删除)。 我经历过最终的一致性'策略,这意味着我的网页中的数据不会与我正在创建/删除的关系一致刷新。 但是我已经看到,通过执行两次put()方法,一致性似乎是有效的。

这符合"最终一致性"定义表明" ...没有提供新的更新......"数据最终将是一致的,因为我正在进行另一次更新(实际上是相同的两次),我想系统会强制一致性。

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

更新:我的目标

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

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

更新:某些代码

这是模型

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和b之间没有祖先关系(并且不可能) 删除关系后,如果从数据存储中再次检索到一个,我仍然可以看到a.services中列出的b.key

1 个答案:

答案 0 :(得分:1)

你的问题的答案在于这句话:

  

当从数据存储中删除关系时,我刷新数据   通过对实体进行另一次查询。

为什么需要新的查询?

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

这显然是一个简化的例子。当我编写具有更复杂用例的学校计划应用程序时,我遇到了类似的挑战 - 单个更改可能会影响所选时间段内的许多实体(例如“每个上学日安排课程直到季度结束”) ,所以我很想简单地运行一个新查询来刷新计划视图。显然,我遇到了最终的一致性问题,因为有时需要创建数十个实体。然后我意识到我已经拥有刷新视图所需的所有数据而无需运行新查询。这是一个更多的代码,但它是一个干净,可靠的解决方案。