I\'m running a contest site where you try to make click number X to win a prize. It\'s written in Django and running on Heroku with PostgreSQL. Each click is saved as an ins
A simple solution would be putting the counter and winner user in the Game model. You can then use select_for_update
to lock the 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
As part of the same transaction you can also record Player
s objects so you also know who clicked and track other info but don't put the number and winner there. To use select_for_update
you need to use postgresql_psycopg2
backend.
Update: Since django set autocommit on by default, you have to wrap the above code in atomic transaction. From django docs
Select for update If you were relying on “automatic transactions” to provide locking between select_for_update() and a subsequent >write operation — an extremely fragile design, but nonetheless possible — you must wrap the relevant code in atomic().
You can decorate your view with @transaction.atomic
:
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()