java – GAE HDR:通过密钥实体检索是否最终在XG事务中保持一致?

考虑“用于事务的”中的第二个示例(“使用命名键更新实体,如果尚不存在则创建”):

https://developers.google.com/appengine/docs/java/datastore/transactions

现在考虑这种情况.多人游戏只允许任何两个玩家之间的单一匹配.为了确保使用每个玩家的键创建一个键.该键用作UniqueMatch实体的键.

所以为了创建一个匹配,创建一个XG事务.在此交易中:

>我们检查是否没有该密钥的UniqueMatch实体.如果使用该键的datastore.get()调用不会抛出EntityNotFoundException,那么我们知道这两个玩家之间的匹配已经存在,所以我们回滚()并向玩家显示一条错误消息.
>我们put()我们需要放置的所有实体来创建一个匹配.这包括UniqueMatch实体,还有其他几个实体.
>然后提交交易.

这似乎工作正常.不过,我注意到我可以在短时间内任意两个球员之间创造两场比赛.在一段时间内(其中一个测试中最多可达10-20秒),我的datastore.get(key)调用即使该键已经被put())抛出EntityNotFoundException.

这似乎是最终的一致性.但不是按实体重组的关键保证是坚定一致的?这个保证是否受到XG交易中的这一事实的影响?

提前致谢,

解决方法

我认为您看到的问题可能是因为数据存储获取(按键或查询)只能在事务开始时看到数据存储的状态.

docs(隔离和一致性):

In a transaction,all reads reflect the current,consistent state of the Datastore at the time the transaction started. This does not include prevIoUs puts and deletes inside the transaction. Queries and gets inside a transaction are guaranteed to see a single,consistent snapshot of the Datastore as of the beginning of the transaction.

另外,在交易之外,您只会看到已经提交的投注(docs):

Entities retrieved from the datastore by queries or gets will only see committed data.

一个可能的解决方案:

在事务外部创建UniqueMatch实体(appengine将不允许您将具有相同密钥的实体放在一起,因此如果具有相同密钥的实体已存在,则会抛出异常).然后,您可以创建/放置在事务中创建匹配所需的其他实体(如果需要).

最后,确保在创建UniqueMatch的键时,他们的键总是以相同的顺序由玩家创建,因为key(playerA,playerB)!= key(playerB,playerA)

相关文章

应用场景 C端用户提交工单、工单创建完成之后、会发布一条工...
线程类,设置有一个公共资源 package cn.org.chris.concurre...
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量