App Engine, transações e idempotência

Por favor me ajude a encontrar o meu mal entendido.

Estou escrevendo um RPG no App Engine. Certas ações que o jogador toma consomem uma certa estatística. Se a estatística chegar a zero, o jogador não poderá realizar mais ações. Eu comecei a me preocupar com trapacear com jogadores - e se um jogador mandasse duas ações muito rapidamente, uma ao lado da outra? Se o código que diminui a estatística não estiver em uma transação, o jogador terá a chance de executar a ação duas vezes. Então, eu deveria quebrar o código que diminui a estatística em uma transação, certo? Por enquanto, tudo bem.

No GAE Python, no entanto, temos isso nodocumentação:

Nota: Se o seu aplicativo receber uma exceção ao enviar uma transação, isso nem sempre significa que a transação falhou. Você pode receber exceções de Tempo Limite, TransactionFailedError ou InternalError nos casos em que as transações foram confirmadas e, eventualmente, serão aplicadas com êxito. Sempre que possível, torne suas transações do Datastore idempotentes para que, se você repetir uma transação, o resultado final seja o mesmo.

Ops Isso significa que a função que eu estava executando é semelhante a esta:

<code>
def decrement(player_key, value=5):
  player = Player.get(player_key)
  player.stat -= value
  player.put()
</code>

Bem, isso não vai funcionar porque a coisa não é idempotente, certo? Se eu colocar um loop de repetição em torno dele (eu preciso em Python? Eu li que não preciso em SO ... mas não consigo encontrá-lo nos documentos) ele pode incrementar o valor duas vezes, certo? Como meu código pode capturar uma exceção, mas o armazenamento de dados ainda confirma os dados ... huh? Como faço para corrigir isso? Este é um caso em que precisotransações distribuídas? Eu realmente?

questionAnswers(4)

yourAnswerToTheQuestion