【发布时间】:2012-10-08 15:08:13
【问题描述】:
考虑“交易用途”中的第二个示例(“使用命名键更新实体,或者如果它尚不存在则创建它”):
https://developers.google.com/appengine/docs/java/datastore/transactions
现在考虑这种情况。多人游戏只允许任何两个玩家之间进行单场比赛。为确保这一点,使用玩家的每个键创建一个键。此键用作 UniqueMatch 实体的键。
因此,为了创建匹配,创建了 XG 交易。在本次交易中:
我们检查是否没有具有该键的 UniqueMatch 实体。如果使用该键的 datastore.get() 调用没有抛出 EntityNotFoundException,那么我们知道这两个玩家之间已经存在匹配,因此我们 rollback() 并向玩家显示错误消息。
我们 put() 我们需要放置的所有实体以创建匹配。这包括 UniqueMatch 实体,以及其他一些实体。
然后提交事务。
这似乎工作正常。但是,我注意到我可以在短时间内在任意两个玩家之间创建两场比赛。在一小段时间内(实际上,在其中一个测试中最多 10-20 秒),我对 datastore.get(key) 的调用会抛出 EntityNotFoundException,即使该键已经被 put()。
这似乎是最终的一致性。但是,实体检索按键难道不能保证强一致性吗?这种保证是否受到在 XG 交易中完成这一事实的影响?
提前致谢,
【问题讨论】:
-
这可能是一个类似的问题。我在 cmets 中弄错了,请参阅 Guido 的评论。 stackoverflow.com/questions/12367904/… 我也确信一旦你从 .put 中取回了一个密钥,你总是可以检索到该项目,但似乎并非如此。 Memcache 也许吧。
-
嗯,我不太确定,Guido 是专门讨论查询,而不是按键检索实体。对于查询,我希望最终保持一致(实际上已正确记录)。 Memcache 可能是一种选择,是的。如果我没有找到更好的方法,我会研究 memcache,谢谢。
-
当然,你确实提到了实体,所以我想我会链接那个讨论。我会赞成你的问题。
-
这很有趣。您是否可以通过让步骤#2 只放置 UniqueMatch 实体来放弃跨组要求,然后查看是否仍然出现相同的行为?另外,关于 10-20 秒的延迟,测试是在开发服务器还是在部署的应用程序中完成?
-
@IbrahimArief:我将尝试在第 2 步中仅将 UniqueMatch 实体放入非 Xg 事务中并回复您。但是,这不适用于生产,因为我们会冒着“悬空”UniqueMatch 实体的风险。关于延迟,这是针对已部署的应用程序的。我无法在开发服务器中重现这一点。谢谢。
标签: java google-app-engine transactions google-cloud-datastore eventual-consistency