Proszę, pomóżcie mi znaleźć moje nieporozumienie.App Engine, transakcje i idempotencja
Piszę RPG na App Engine. Pewne działania, które gracz bierze, zużywają pewną statystykę. Jeśli stat osiągnie zero, gracz nie może wykonać więcej akcji. Zacząłem się jednak martwić o oszustów - co jeśli gracz wysłał dwie akcje bardzo szybko, tuż obok siebie? Jeśli kod, który zmniejsza statystyki, nie znajduje się w transakcji, wówczas gracz ma szansę wykonać akcję dwukrotnie. Więc powinienem owinąć kod, który zmniejsza statystyki w transakcji, prawda? Jak na razie dobrze.
W GAE Python, choć mamy to w documentation:
Uwaga: Jeśli aplikacja odbiera wyjątek przy składaniu transakcję, to nie zawsze znaczy że transakcja nie powiodła się. Możesz otrzymywać wyjątki Timeout, TransactionFailedError lub InternalError w przypadkach, w których transakcje zostały zatwierdzone i ostatecznie zostaną pomyślnie zastosowane . Gdy tylko jest to możliwe, twórz transakcje Datastore idempotent tak, aby po powtórzeniu transakcji wynik końcowy był taki sam.
Whoops. Oznacza to, że funkcja biegałam, które wygląda następująco:
def decrement(player_key, value=5):
player = Player.get(player_key)
player.stat -= value
player.put()
Dobrze, że nie zadziała, ponieważ sprawa nie jest idempotent, prawda? Jeśli umieściłem wokół niego pętlę retry (czy muszę w Pythonie? Czytałem, że nie muszę na SO ... ale nie mogę znaleźć go w dokumentach) może on zwiększyć wartość dwukrotnie, dobrze? Ponieważ mój kod może wychwycić wyjątek, ale magazyn danych nadal zatwierdził dane ... huh? Jak to naprawić? Czy jest to przypadek, w którym potrzebuję distributed transactions? Czy ja naprawdę?
Cóż, tak, i to jest dobra uwaga ... ale zanim zaśmiecę mój kod z garstką trudnych do zdiagnozowania, trudnych do ... rozmnażaj błędy Chciałbym się dowiedzieć, jaki wzór powinienem tu wybrać. –
Twój wzór jest na dobrej drodze, ale GAE ma sporo frustrujących niuansów, które utrudniają precyzyjne wykonanie chirurgiczne. W moim doświadczeniu z GAE, czasami jest to warte wysiłku, a czasem nie. –
@ TravisWebb Nie zgadzam się. Bezpieczeństwo transakcji nie jest "przedwczesną optymalizacją", a kolizje transakcji nie są szczególnie prawdopodobne. –