Django seems to work asyncroniously for some reason

时间:2017-04-06 17:12:19

标签: django asynchronous django-views gunicorn

I have a view:

from app.models import Product, Sell

def buy(request):

    product = Product.objects.filter(user__isnull=True).first()

    if product:

        product.user = request.user
        product.save()

        Sale.objects.create(user=request.user, product=product)

I have only one Product instance in database that has not been sold (assigned to user)

And if I run this piece of JS in browser console:

for (i=1;i<100;i++) {
    $.get('/buy/', function(data) {console.log(data)});
}

In the result I have a User with random amount of Sale objects (from 1 to 5) with the one same related product. user.sale_set.count() prints 3, but there were nothing before

But it should not because Sale should not been created if Product already had a user .filter(user__isnull=True)

So, that seems that probably Django works async for some reason, or I am just an idiot?

That is very strange and new behaviour for me, probably my gunicorn systemd setup can help?

[Unit]
Description=my_project daemon
After=network.target

[Service]
User=root
Group=nginx
WorkingDirectory=/www/my_project
;ExecStart=/env/my_project/bin/gunicorn --workers 3 --bind unix:/www/my_project/myproject.sock core.wsgi:application
ExecStart=/env/my_project/bin/gunicorn core.wsgi --timeout 10000 --workers=25 -b 0.0.0.0:8000

[Install]
WantedBy=multi-user.target

1 个答案:

答案 0 :(得分:1)

由于竞争条件,您可以使用select_for_update

解决此问题
from django.db import transaction

with transaction.atomic():
    product = Product.objects.select_for_update().filter(user__isnull=True).first()
    if product:
        product.user = request.user
        product.save()