App Engine, transakcje i idempotencja

Pomóż mi znaleźć moje nieporozumienie.

Piszę RPG na App Engine. Niektóre akcje, które gracz bierze, zużywają określoną statystykę. Jeśli statystyka osiągnie zero, gracz nie może wykonywać więcej akcji. Zacząłem się jednak martwić o oszukiwanie graczy - co jeśli gracz szybko wysłał dwie akcje, tuż obok siebie? Jeśli kod zmniejszający statystykę nie znajduje się w transakcji, gracz ma szansę wykonać akcję dwukrotnie. Więc powinienem zawrzeć kod, który zmniejsza statystyki w transakcji, prawda? Jak na razie dobrze.

W GAE Python mamy to wdokumentacja:

Uwaga: Jeśli Twoja aplikacja otrzyma wyjątek podczas przesyłania transakcji, nie zawsze oznacza to, że transakcja nie powiodła się. Możesz otrzymać wyjątki Timeout, TransactionFailedError lub InternalError w przypadkach, w których transakcje zostały zatwierdzone i ostatecznie zostaną pomyślnie zastosowane. Kiedy tylko jest to możliwe, spraw, by transakcje Datastore były idemotentne, aby w przypadku powtórzenia transakcji wynik końcowy był taki sam.

Ups. Oznacza to, że funkcja, którą uruchomiłem, wygląda tak:

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

Cóż, to nie zadziała, ponieważ rzecz nie jest idempotentna, prawda? Jeśli ustawię pętlę ponownej próby (czy muszę to zrobić w Pythonie? Czytałem, że nie muszę tego robić na SO ... ale nie mogę go znaleźć w dokumentach), może to zwiększyć wartość dwukrotnie, dobrze? Ponieważ mój kod może przechwycić wyjątek, ale magazyn danych nadal wprowadził dane ... co? Jak to naprawić? Czy to jest przypadek, w którym potrzebujętransakcje rozproszone? Czy ja naprawdę

questionAnswers(4)

yourAnswerToTheQuestion