私の誤解を見つけるのを手伝ってください。
AppEngineでRPGを書いています。プレイヤーが行う特定のアクションは、特定の統計を消費します。統計がゼロに達すると、プレイヤーはそれ以上アクションを実行できなくなります。しかし、私はプレイヤーをだますことについて心配し始めました-プレイヤーが2つのアクションを非常に速く、隣り合って送信した場合はどうなりますか?統計をデクリメントするコードがトランザクションにない場合、プレーヤーはアクションを2回実行する可能性があります。だから、トランザクションで統計を減らすコードをラップする必要がありますよね?ここまでは順調ですね。
ただし、GAE Pythonでは、ドキュメントに次のように記載されています。
注:トランザクションの送信時にアプリが例外を受け取った場合、それは必ずしもトランザクションが失敗したことを意味するわけではありません。トランザクションがコミットされ、最終的に正常に適用される場合は、Timeout、TransactionFailedError、またはInternalError例外を受け取る可能性があります。可能な限り、データストアトランザクションをべき等にして、トランザクションを繰り返しても最終結果が同じになるようにします。
おっと。これは、私が実行していた関数が次のようになっていることを意味します。
def decrement(player_key, value=5):
player = Player.get(player_key)
player.stat -= value
player.put()
まあ、べき等ではないので、それはうまくいきませんよね?再試行ループをその周りに配置すると(Pythonで実行する必要がありますか?SOで実行する必要がないことを読みました...しかし、ドキュメントで見つけることができません)、値が2回インクリメントされる可能性があります。右?私のコードは例外をキャッチできますが、データストアはまだデータをコミットしているので...え?これを修正するにはどうすればよいですか?これは分散トランザクションが必要な場合ですか?私は本当にですか?