PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Evitando condições de corrida, Django + Heroku + PostgreSQL


Uma solução simples seria colocar o usuário contador e vencedor no modelo de jogo. Você pode então usar select_for_update para bloquear o 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 da mesma transação, você também pode gravar Player s para que você também saiba quem clicou e acompanhe outras informações, mas não coloque o número e o vencedor lá. Para usar select_for_update você precisa usar postgresql_psycopg2 Processo interno.

Atualização: Como o django define o autocommit por padrão, você precisa envolver o código acima em uma transação atômica. Do django docs

Você pode decorar sua visualização com @transaction.atomic :
from django.db import transaction

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