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)