1

我正在尝试设计我的应用程序引擎数据存储区代码,并且已经想到了一个潜在问题,并且无法在文档中找到有关在给定情况下会发生什么的任何具体信息。

当我去存储一个具有祖先的实体时,在存储它之前我检查以确保它的祖先存在于一个事务中,如果它不存在,我创建祖先。接下来,我开始另一个存储实体的事务,使用在上一步中找到或创建的祖先键创建它。在使用单个用户或极少数用户进行测试时,这永远不会成为问题,因为并发修改的机会最少,但是一旦部署,我担心的是在第一个事务之间的时间(创建/检索祖先) 和第二个事务(添加一个实体作为祖先的后代)另一个用户可能会删除祖先。

我最初的想法是让这一切作为一个事务发生,但在祖先不存在并且必须创建的情况下,检查我要创建的实体是否存在的祖先查询将失败,因为快照隔离模型数据存储。但是,我不确定这是否正确。

有人对此事有任何了解吗?如果祖先被删除,实体提交是否仍然可以使用现在不引用任何内容的父键?这会重新创建父级,以便将来对其进行检查将返回相同的密钥吗?我会测试这种情况,但我无法设计出一种切实可行的方法。

4

2 回答 2

1

一种可能的解决方案是尝试直接获取祖先(而不是查询),如果对象为空,则在事务中同时创建祖先和后代。这将模拟跨组事务(XG 事务),因为这两个实体在创建时将不属于同一个实体组。

有关 XG 交易的更多信息,请查看:

希望这可以帮助!

于 2012-10-12T07:51:28.103 回答
0

我相信答案是:“的,它仍然会被创建”。

此行为不应特定于 Python 或 Java API。我尝试创建一个实体,其中密钥具有不存在的祖先,并且它似乎在 Google Cloud Datastore 中工作。

我猜这背后的逻辑是基于 Datastore 回答问题的过程:“这个键属于哪个实体组?” 我假设该决定是通过检查“顶级”祖先来做出的,这意味着是否存在具有顶级祖先的 Key 无关紧要。

也就是说,如果Key.from_path('Kind1', 'parent')两者Key.from_path('Kind1', 'parent', 'Kind1', 'child')都放在同一个实体组中(彼此独立),那么它们添加的顺序是无关紧要的,第一个的存在与第二个所在的组无关。

一些示例代码:

from gcloud.datastore import demo
from gcloud.datastore.entity import Entity
from gcloud.datastore.key import Key

dataset = demo.get_dataset()
entity = Entity()
key = Key.from_path('Person', 'parent', 'Person', 'child').dataset(dataset)
entity = entity.key(key)
entity.save()

请注意,没有“父级”(kind='Person', key_name='parent'不存在的实体)。

于 2014-04-20T20:16:02.387 回答