I am developing some code where i need to save in database big amount of data. Response is taking about a minute or more. So I decided to move that code in celery task. I have view that calls celery task. Problem here is that you shouldn't be able to receive status 200 from that view if celery task is still running for the same record in database.
There i used select_for_update statement for row level lock like:
site = self.get_object()
try:
with transaction.atomic():
Site.objects.select_for_update(nowait=True).filter(pk=site.pk)
except DatabaseError:
raise ObjectLockedException
in view, and:
with transaction.atomic():
models.Site.objects.select_for_update(nowait=True).get(pk=site_id)
....
in task. As you see, the code is the same.
My expected result is that if celery task has started and acquired lock for specific Site with site_id but it is not finished yet, I should catch the DatabaseError in the specified view. This is not the case, select_for_update in view passes without any exception even the task for same Site is still running.
Another funny thing is that on line serializer.save(), below the first snippet of code, in the specified view, my code waits for task to finish processing.
Am I doing it wrong?