本文介绍了Google App Engine数据存储:处理最终的一致性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这符合最终一致性定义,该定义规定......未提供新更新......数据最终将保持一致,并且我正在进行另一次更新(实际上是两次)我想系统会强制一致性。



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



更新:我的AIM

我有一个B类型另一个实体的列表,类型A的实体可以依靠。
它是一个多对多的关系,所以
一个服务b可以被许多实体a使用a
一个实体a可以由许多b类型的服务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()
serveEntities = 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

为什么你需要一个新的查询?



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



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


I am developing a GAE web application and I need to create and remove associations among instances of two Entities which have no ancestor relationship (also consider the same instance may have multiple associations that may vary in time while the ancestor relationship, once created, can't be removed). I have experienced the 'eventual consistency' policy which means data in my web page are not refreshed coherently with the relationships I am creating/removing. However I have seen that by executing the put() method twice the consistency seems to be force.

This is compliant with the "Eventual Consistency" definition which states that "... provided no new updates are made ..." data will eventually be consistent and, since I am making another update (actually the same two times) I guess the system forces the consistency.

Am I right? Is there any other more elegant way of doing it?

Update: My AIM

Consider I have a list of entities of type A, it doesn't matter what they actually represent, let's say they represent the main entities of my businessI have a list of another entities of type B representing services the entities of type A can rely on. it is a many to many relationship so A service b can be used by many entities a of type AAn entity a can be served by many services b of type B

I have a web page allowing me to create such relationship, (a Jinja2 template with a Jquery Ajax callback from the client side and a webapp2 python request handler relying on the datastore in the server side). When a relationship is removed from the datastore I refresh the data by making another query on the a entity and depicting the list of b keys it has related. In this case I still see the removed b.key in the list of b keys related to a. Which is not what I would expect.

UPDATE: SOME CODE

here is the model

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

class B(ndb.Model):
    name = ndb.StringProperty()
    servedEntities = ndb.KeyProperty(repeated=True)

here is the code I use to create the relationship

                a.services.append(b.key);
                b.servedEntities.append(a.key);
                a.put()
                b.put()

here is the code I use to remove the relationship

               a.services.remove(b.key);
               b.servedEntities.remove(a.key);
               a.put()
               b.put()

There is no ancestor relationship between a and b (and there can not be)After the relationship removal I if retrieve again a from the Datastore I can still see b.key listed in a.services

解决方案

The answer to your question lies in this statement:

Why do you need a new query?

Let's say a user subscribed to services x, y and z. Now a user tells you to drop service z from the list. You go to the Datastore and make the necessary change. Instead of running a new query, however, which may still show z among the returned entities, you can simply remove z from your user entity on the client side and update the UI accordingly.

This is obviously a simplified example. I faced a similar challenge when I wrote the school scheduling app, which had a more complex use case - a single change may affect many entities in the selected time period (e.g. "schedule a lesson every school day until the end of the quarter"), so I was tempted to simply run a new query to refresh the schedule view. Obviously, I ran into the eventual consistency problem magnified by the fact that sometimes dozens of entities had to be created. Then I realized that I already have all the data that I need to refresh the view without running a new query. It's a bit more code, but it's a clean and reliable solution.

这篇关于Google App Engine数据存储:处理最终的一致性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 15:40