简体   繁体   English

GAE HDR:按键的实体检索最终是否在XG事务中保持一致?

[英]GAE HDR: Are entity retrievals by key eventually consistent within a XG transaction?

Consider the second example in "Uses for Transactions" ("update an entity with a named key, or create it if it doesn't yet exist"): 考虑“使用事务”中的第二个示例(“使用命名密钥更新实体,或者如果它尚不存在则创建它”):

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

Now consider this scenario. 现在考虑这种情况。 A multiplayer game allows only a single match between any two players. 多人游戏只允许任何两个玩家之间的单一匹配。 To ensure that, a key is created using each of the player's keys. 为了确保这一点,使用每个玩家的键创建一个键。 This key is used as the key of a UniqueMatch entity. 此键用作UniqueMatch实体的键。

So in order to create a match, a XG transaction is created. 因此,为了创建匹配,将创建XG事务。 Within this transaction: 在此交易中:

  1. We check if there isn't a UniqueMatch entity with that key already. 我们检查是否已存在具有该密钥的UniqueMatch实体。 If a datastore.get() call using that key does not throw EntityNotFoundException, then we know that a match between those two players already exists, so we rollback() and show an error message to the players. 如果使用该键的datastore.get()调用没有抛出EntityNotFoundException,那么我们知道这两个玩家之间的匹配已经存在,所以我们回滚()并向玩家显示错误消息。

  2. We put() all entities we need to put in order to create a match. 我们将()所有需要放入的实体放入以创建匹配项。 This includes the UniqueMatch entity, plus some other few entities. 这包括UniqueMatch实体以及其他一些实体。

  3. The transaction is then committed. 然后提交事务。

This seems to work fine. 这似乎工作正常。 However, I noticed I can create two matches between any two players within a short time window. 但是,我注意到我可以在短时间内在任意两个玩家之间创建两场比赛。 For a small period of time (up to 10-20s in one of the tests, actually), my calls to datastore.get(key) throw EntityNotFoundException even though that key has already been put(). 在一小段时间内(实际上其中一个测试中最多10-20秒),我对datastore.get(key)的调用抛出了EntityNotFoundException,即使该键已经被put()。

This seems to be eventual consistency. 这似乎是最终的一致性。 But aren't entity retrivals by key guaranteed to be strongly consistent? 但是关键的实体回顾不是保证强烈一致吗? Is this guarantee affected by the fact that this is done within a XG transaction? 此保证是否受到在XG交易中完成的事实的影响?

Thanks in advance, 提前致谢,

I think the issue you're seeing may be because datastore gets (by key or queries) only see the state of the datastore at the start of the transaction. 我认为您遇到的问题可能是因为数据存储区(通过密钥或查询)只能在事务开始时看到数据存储区的状态。

From the docs (under isolation and consistency): 文档 (隔离和一致性):

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. 查询和获取事务内部保证在事务开始时看到数据存储的单个一致快照。

Also, outside of the transaction, you'll only see puts that have been committed ( docs ): 此外,在交易之外,您只会看到已提交的看跌期权( docs ):

Entities retrieved from the datastore by queries or gets will only see committed data. 通过查询或获取从数据存储区检索的实体将仅查看已提交的数据。

A possible solution: 可能的解决方案:

Create the UniqueMatch entity outside of the transaction (appengine won't allow you to put an entity with the same key, so it'll throw an exception if the entity with the same key already exists). 在事务之外创建UniqueMatch实体(appengine不允许您放置具有相同键的实体,因此如果具有相同键的实体已存在,则会抛出异常)。 You can then create/put the other entities required to create a match inside a transaction (if need be). 然后,您可以创建/放置在事务内创建匹配所需的其他实体(如果需要)。

Lastly, make sure when creating the key for the UniqueMatch that they key is always created with the players in the same order because key(playerA,playerB)!=key(playerB,playerA) 最后,确保在为UniqueMatch创建密钥时,他们的密钥总是以相同的顺序创建,因为key(playerA,playerB)!=key(playerB,playerA)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM