当前位置: 首页 > 知识库问答 >
问题:

谷歌应用引擎数据存储:处理最终一致性

年业
2023-03-14

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

这符合“最终一致性”定义,该定义规定“…如果没有进行新的更新…”数据最终会保持一致,因为我正在进行另一次更新(实际上是两次相同的更新),我想系统会强制保持一致性。

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

更新:我的目标

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

我有一个网页,允许我创建这样的关系(一个Jinja2模板,带有来自客户端的Jquery Ajax回调和依赖于服务器端数据存储的webapp2 python请求处理程序)。当从数据存储中删除关系时,我通过对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和b之间没有祖先关系(也不可能有)关系删除后,如果再次从数据存储中检索a,我仍然可以看到a.services中列出的b.key

共有1个答案

燕承安
2023-03-14

你的问题的答案在于以下陈述:

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

为什么需要新查询?

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

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

 类似资料:
  • 我正在看新的谷歌云数据存储,看起来很棒。但有件事我不明白。。。它应该替代谷歌应用引擎数据存储吗?我如何在GAE内部使用它?它们之间有什么区别? 我在Java有一个GAE应用程序,它使用3个实体,每个实体都有数千行,我需要经常做连接...

  • Google API客户端库 Google云存储客户端库 Google云存储API Google Cloud Storage JSON API Java客户端库 我仍然不知道每一个都是做什么的,我不知道如何在我的android客户端中实现云存储。 如果我使用云存储,为什么我需要应用引擎后端应用?我的后端不需要API,对吗?我可以使用Google Cloud Storage JSON API直接消耗

  • 在GAE中,我只使用默认域名:https://*。appspot。com,所以我不需要生成自签名证书。 谷歌应用程序引擎文档指定应用程序的运行方式。yaml应配置为服务于SSL连接: https://cloud.google.com/appengine/docs/standard/go/config/appref#handlers_secure 但为了在Go中提供HTTPS连接,我编写了以下代码示

  • 我的应用程序需要一堆秘密来运行:数据库凭据、API凭据等。它在Google App Engine StandardJava11中运行。我需要这些秘密作为环境变量或应用程序的参数,以便我的框架可以拾取它们并相应地建立连接。我的特定框架是Spring Boot,但我相信Django、Rails和许多其他框架使用相同的方法。 最好的方法是什么? 我对这个问题的一个答案是使用谷歌云密钥管理,这看起来很有希