请帮助我找到我的误会。
我正在App Engine上编写RPG。玩家采取的某些 Action 消耗了一定的属性。如果统计信息达到零,则玩家将无法再执行任何操作。不过,我开始担心作弊者-如果玩家很快就发出了两个 Action ,彼此相邻又该怎么办?如果减少统计量的代码不在交易中,则玩家有机会两次执行该操作。因此,我应该包装在事务中减少统计信息的代码,对吗?到现在为止还挺好。
不过,在GAE Python中,我们在documentation中包含了它:
哎呀这意味着我正在运行的函数如下所示:
def decrement(player_key, value=5):
player = Player.get(player_key)
player.stat -= value
player.put()
好吧,那是行不通的,因为那东西不是幂等的,对吧?如果我在它周围放了一个重试循环(我需要在Python中使用吗?我读到我不需要在SO ...但是我在文档中找不到它)可能会使值增加两次,正确的?由于我的代码可以捕获异常,但是数据存储区仍提交了数据……是吗?我该如何解决?这是我需要distributed transactions的情况吗?我真的吗
最佳答案
首先,尼克的答案不正确。 DHayes的事务不是幂等的,因此,如果它多次运行(即,当第一次尝试被认为失败时重试,而没有失败则重试),则该值将被递减多次。尼克说:“数据存储区会检查自获取实体以来是否已对实体进行修改”,但是由于两个事务具有单独的获取,而第二个获取是在第一个事务完成后进行的,因此这不能避免问题。
要解决该问题,可以通过创建“事务键”并将该键记录在新实体中作为事务的一部分来使事务成为幂等。第二个事务可以检查该事务 key ,如果找到,将不执行任何操作。您对交易完成感到满意或放弃重试后,即可删除交易 key 。
我想知道“绝对稀有”对AppEngine(百万分之一或十亿分之一?)意味着什么,但是我的建议是,金融事务需要幂等交易,但对于游戏分数,甚至“生命” ;-)