gue*_*tli 5 django postgresql concurrency race-condition
想象一下,你有一个简单的工作项表:
|ID |OWNER|...
+---+-----+---
|123| |...
|456| |...
|789| |...
Run Code Online (Sandbox Code Playgroud)
我们希望提供一个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
Run Code Online (Sandbox Code Playgroud)
你可以做:
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()
Run Code Online (Sandbox Code Playgroud)
使用 时skip_locked=True,事务会跳过锁定的行,因此是非阻塞的。作为奖励,您只需要保存到数据库一次。
| 归档时间: |
|
| 查看次数: |
159 次 |
| 最近记录: |