我正在尝试设计我的应用引擎数据存储区代码并考虑到潜在的问题,并且无法在文档中找到有关在给定情况下会发生什么的任何具体信息。
当我去存储具有祖先的实体时,在存储之前我检查以确保它的祖先存在于一个事务中,如果它不存在,我创建祖先。接下来,我开始另一个事务,我存储实体,使用在上一步中找到或创建的祖先密钥创建它。在使用单个用户或极少数用户进行测试时,这永远不会成为问题,因为并发修改机会最少,但是一旦部署,我担心的是在第一个事务(创建/检索祖先)之间的时间)和第二个事务(添加一个实体作为祖先的后代)另一个用户可能会删除祖先。
我最初的想法是将这一切都作为一个事务发生,但是在祖先不存在且必须被创建的情况下,检查我想要创建的实体是否存在的祖先查询将因为快照而失败数据存储的隔离模型。但是,我不确定这是否正确。
有没有人对此事有任何了解?如果祖先被删除,那么实体提交是否仍然可以使用现在没有引用的父键?这会重新创建父级,以便将来检查它将返回相同的密钥吗?我会测试这种情况,但我无法设计出实用的方法。
答案 0 :(得分:1)
一种可能的解决方案是尝试直接获取祖先(而不是Query),如果对象为null,则在事务中创建祖先和后代。这将模仿跨组事务(XG事务),因为创建时这两个实体将不属于同一实体组。
有关XG交易的更多信息,请查看:
希望这有帮助!
答案 1 :(得分:0)
我相信答案是:“是,它仍会被创建”。
此行为不应特定于Python或Java API。我尝试创建一个实体,其中密钥具有不存在的祖先,并且它似乎在Google Cloud Datastore中有效。
我猜这背后的逻辑是基于数据存储区回答问题的过程:“这个密钥属于哪个实体组?”我认为通过检查“顶级”祖先来做出决定,这意味着无论是否存在 顶级祖先的密钥都无关紧要。< / p>
也就是说,如果要将 一些示例代码: 请注意,没有“父级”(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'
不存在的实体)。