假设您有一个包含工作项的简单表格:
|ID |OWNER|...
+---+-----+---
|123| |...
|456| |...
|789| |...
我们想提供一个 http API 来获取下一个还没有所有者的工作项。
我们使用 PostgreSQL。
我们使用 Django-ORM 访问表。
如果 API 被许多用户同时访问,我猜想会有几个竞争条件。
我如何确保使用给定的工具(PostgreSQL、Django)解决所有竞争条件(如果将工作项提供给两个或多个用户,这是一个主要错误)。
最佳答案
使用 Django 1.11,select_for_update开始支持 skip_locked
。这意味着您可以节省 save()
调用,因为您不必立即将其分配给所有者。
例如,建立在@user73657 的回答之上:
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'])
# process work_item
你可以这样做:
with transaction.atomic():
work_item = WorkItem.objects.select_for_update(skip_locked=True).filter(owner__isnull=True).first()
work_item.owner = request.user
# process work_item, edit other fields
work_item.save()
使用skip_locked=True
,事务会跳过锁定的行,因此是非阻塞的。作为奖励,您只需要保存到数据库一次。
关于django - 使用 PostgreSQL 在 Django 中获取下一个工作项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43682276/