PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Éviter les conditions de concurrence, Django + Heroku + PostgreSQL

Une solution simple consisterait à placer le compteur et l'utilisateur gagnant dans le modèle de jeu. Vous pouvez ensuite utiliser select_for_update pour verrouiller l'enregistrement :

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

Dans le cadre de la même transaction, vous pouvez également enregistrer Player s objets afin que vous sachiez également qui a cliqué et suivez d'autres informations, mais n'y mettez pas le numéro et le gagnant. Pour utiliser select_for_update vous devez utiliser postgresql_psycopg2 backend.

Mise à jour : Étant donné que Django a activé la validation automatique par défaut, vous devez envelopper le code ci-dessus dans une transaction atomique. À partir de django documents

Vous pouvez décorer votre vue avec @transaction.atomic :

from django.db import transaction

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