Пожалуйста, помогите мне найти мое непонимание.App Engine, транзакции и идемпотентность
Я пишу RPG в App Engine. Определенные действия, которые игрок берет, потребляют определенный стат. Если стат достигает нуля, игрок не может принимать больше никаких действий. Однако я начал беспокоиться об обманах игроков - что, если игрок отправил два действия очень быстро, прямо рядом друг с другом? Если код, который уменьшает стат, не находится в транзакции, тогда у игрока есть шанс выполнить действие дважды. Итак, я должен обернуть код, который уменьшает стат в транзакции, правильно? Все идет нормально.
В GAE Python, хотя, у нас есть это в documentation:
Примечание: Если ваше приложение получает исключение при подаче транзакции, он не всегда означает, что сделка не удалась. Вы можете получить Timeout, TransactionFailedError или Исключения InternalError в случаях, когда транзакции были совершены, и в конечном итоге будет применено . Когда это возможно, сделайте свои транзакции Datastore idempotent так, чтобы , что если вы повторите транзакцию, конечный результат будет таким же.
Упс. Это означает, что функция я бегу, что выглядит следующим образом:
def decrement(player_key, value=5):
player = Player.get(player_key)
player.stat -= value
player.put()
Ну, это не сработает, потому что дело не идемпотентна, верно? Если я поставил вокруг него цикл повторения (нужно ли мне на Python? Я читал, что мне не нужно на SO ... но я не могу найти его в документах), он может увеличить значение дважды, правильно? Так как мой код может поймать исключение, но хранилище данных все еще передало данные ... а? Как это исправить? Это случай, когда мне нужно distributed transactions? Неужели?
Ну, да, и это хороший момент ... но прежде, чем я поместил свой код с кучей труднодоступных для диагностики, воспроизведите ошибки, которые я хотел бы узнать, какой шаблон мне нужно делать здесь. –
Ваша модель находится на правильном пути, но у GAE есть довольно много неудобных нюансов, которые делают сложную хирургическую точную реализацию, такую как это. По моему опыту с GAE, иногда это стоит усилий, а иногда и нет. –
@TravisWebb Не согласен. Транзакционная безопасность не является «преждевременной оптимизацией», и транзакционные столкновения особенно маловероятны. –