Por favor, ayúdame a encontrar mi malentendido.App Engine, transacciones e idempotencia
Estoy escribiendo un juego de rol en App Engine. Ciertas acciones que el jugador toma consumen una determinada estadística. Si la estadística llega a cero, el jugador no puede tomar más acciones. Sin embargo, comencé a preocuparme por engañar a los jugadores: ¿qué pasaría si un jugador enviara dos acciones muy rápido, uno al lado del otro? Si el código que disminuye la estadística no está en una transacción, entonces el jugador tiene la posibilidad de realizar la acción dos veces. Entonces, debo ajustar el código que reduce la estadística en una transacción, ¿verdad? Hasta aquí todo bien.
En GAE Python, sin embargo, tenemos esto en el documentation:
Nota: Si su aplicación recibe una excepción cuando la presentación de una transacción, no siempre significa que la transacción ha fallado. Puede recibir excepciones Timeout, TransactionFailedError o InternalError en los casos en que se hayan confirmado transacciones y, finalmente, se aplicará . Siempre que sea posible, defina las transacciones de su Almacén de datos de manera que que si repite una transacción, el resultado final será el mismo.
Whoops. Eso significa que la función estaba corriendo que tiene este aspecto:
def decrement(player_key, value=5):
player = Player.get(player_key)
player.stat -= value
player.put()
Bueno, eso no va a funcionar porque la cosa no es idempotente, ¿verdad? Si pongo un ciclo de reintento alrededor (¿tengo que hacerlo en Python? He leído que no necesito hacerlo en SO ... pero no puedo encontrarlo en los documentos) podría incrementar el valor dos veces, ¿derecho? Dado que mi código puede detectar una excepción, pero el almacén de datos aún cometió los datos ... ¿eh? ¿Cómo puedo solucionar esto? ¿Es este un caso en el que necesito distributed transactions? ¿De verdad?
Bueno, sí, y es un buen punto ... pero antes de escribir mi código con un montón de difícil de diagnosticar, difícil de - reproducir errores Me gustaría aprender qué patrón debería seguir aquí. –
Su patrón está en el camino correcto, pero GAE tiene bastantes matices frustrantes que dificultan la implementación quirúrgica precisa como esta. En mi experiencia con el GAE, a veces vale la pena el esfuerzo, y a veces no. –
@TravisWebb No estoy de acuerdo. La seguridad transaccional no es una "optimización prematura", ni las colisiones de transacción son particularmente improbables. –