PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Evitando condizioni di gara, Django + Heroku + PostgreSQL

Una soluzione semplice sarebbe quella di inserire il contatore e l'utente vincitore nel modello di gioco. Puoi quindi utilizzare select_for_update per bloccare il record:

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

Come parte della stessa transazione puoi anche registrare Player s oggetti in modo da sapere anche chi ha cliccato e tenere traccia di altre informazioni ma non inserire il numero e il vincitore lì. Per utilizzare select_for_update devi usare postgresql_psycopg2 backend.

Aggiornamento: Poiché django ha impostato l'autocommit per impostazione predefinita, devi avvolgere il codice sopra nella transazione atomica. Da django documenti

Puoi decorare la tua vista con @transaction.atomic :

from django.db import transaction

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