sql >> Base de Datos >  >> RDS >> PostgreSQL

Evitar condiciones de carrera, Django + Heroku + PostgreSQL

Una solución sencilla sería poner el contador y el usuario ganador en el modelo Game. Luego puede usar select_for_update para bloquear el registro:

game = Game.objects.select_for_update().get(pk=gamepk)
if game.number + 1 == X
    # he is a winner
    game.winner = request.user
    game.number = game.number + 1
    game.save()

else:
    # u might need to stop the game if a winner already decided

Como parte de la misma transacción, también puede registrar Player s objetos para que también sepa quién hizo clic y rastree otra información, pero no ponga el número y el ganador allí. Para usar select_for_update necesitas usar postgresql_psycopg2 backend.

Actualización: Dado que Django configuró la confirmación automática de forma predeterminada, debe envolver el código anterior en una transacción atómica. De django docs

Puede decorar su vista con @transaction.atomic :

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()