With Django 1.11, select_for_update started supporting skip_locked . This means that you can save save() calls, since you do not need to assign them to the owner right away.
For example, building on top of @ user73657 the answer:
with transaction.atomic(): work_item = WorkItem.objects.select_for_update().filter(owner__isnull=True).first() work_item.owner = request.user work_item.save(update_fields=['owner'])
You can do:
with transaction.atomic(): work_item = WorkItem.objects.select_for_update(skip_locked=True).filter(owner__isnull=True).first() work_item.owner = request.user
With skip_locked=True transaction skips a locked row and therefore does not block. As a bonus, you will only need to save it in db once.
source share