django - 使用 PostgreSQL 在 Django 中获取下一个工作项

标签 django postgresql concurrency race-condition

假设您有一个包含工作项的简单表格:

|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/

相关文章:

python - Django 从字符字段迁移到整数字段?

ruby-on-rails - 在 ruby​​ on rails 中使用 pg_search 在全文搜索之前限制 domaing

arrays - Postgres - 通过 SQL 插入一个 varchar 数组

c# - C#中的UTF8字符串变量

java - 同步 ID 并删除

python - 如何将 @cache_page 装饰器与基于 Django 类的 View 一起使用?

python - 在 Django 管理仪表板中将 Django Flatpage Label 更改为另一个名称

jquery - 在 django 中制作简单的可排序播放列表的最佳方法

c++ - 为什么 lock_guard 是模板?

c++ - winrt/c++ : await result from dispatched task