Bitte helfen Sie mir mein Missverständnis zu finden.App Engine, Transaktionen und Idempotenz
Ich schreibe ein RPG auf App Engine. Bestimmte Aktionen des Spielers verbrauchen einen bestimmten Wert. Wenn der Wert Null erreicht, kann der Spieler keine Aktionen mehr ausführen. Ich fing an, mir Gedanken darüber zu machen, ob ich Spieler betrügen könnte - was wäre, wenn ein Spieler zwei Aktionen sehr schnell, direkt nebeneinander schickte? Wenn der Code, der den Wert dekrementiert, nicht in einer Transaktion ist, hat der Spieler die Chance, die Aktion zweimal auszuführen. Also sollte ich den Code, der die Statistik dekrementiert, in eine Transaktion einbinden, oder? So weit, ist es gut.
In GAE Python, aber wir haben dies in den documentation:
Hinweis: Wenn Ihre Anwendung eine Ausnahme empfängt, wenn eine Transaktion einreichen, ist es nicht bedeutet immer, dass die Transaktion fehlgeschlagen. Sie können Timeout-, TransactionFailedError- oder InternalError-Exceptions in Fällen empfangen, in denen Transaktionen festgeschrieben wurden und schließlich erfolgreich angewendet werden. Wenn möglich, machen Sie Ihre Datastore-Transaktionen so Idempotent, dass , dass, wenn Sie eine Transaktion wiederholen, das Endergebnis das gleiche sein wird.
Whoops. Das bedeutet, dass die Funktion, die ich, dass lief wie folgt aussieht:
def decrement(player_key, value=5):
player = Player.get(player_key)
player.stat -= value
player.put()
Nun, das wird nicht funktionieren, weil die Sache nicht idempotent, nicht wahr? Wenn ich eine Wiederholungsschleife darum herumlege (muss ich in Python? Ich habe gelesen, dass ich nicht auf SO muss ... aber ich kann es nicht in den Dokumenten finden), könnte es den Wert zweimal erhöhen, Recht? Da mein Code eine Ausnahme abfangen kann, aber der Datenspeicher die Daten trotzdem festlegt ... hm? Wie behebe ich das? Ist das ein Fall, wo ich distributed transactions brauche? Tue ich wirklich?
Nun, ja, und es ist ein guter Punkt ... aber bevor ich meinen Code mit einer Reihe von schwer zu diagnostizieren, schwer zu Fehler zu reproduzieren Ich möchte gerne lernen, welches Muster ich hier anwenden sollte. –
Ihr Muster ist auf dem richtigen Weg, aber GAE hat einige frustrierende Nuancen, die eine solche chirurgisch präzise Implementierung erschweren. Nach meiner Erfahrung mit der GAE ist es manchmal die Mühe wert und manchmal nicht. –
@TravisWebb Stimme nicht zu. Transaktionssicherheit ist keine "vorschnelle Optimierung", ebenso wenig sind Transaktionskollisionen besonders unwahrscheinlich. –