【发布时间】:2021-09-30 15:20:54
【问题描述】:
我正在使用的documentation for Django 2.2 给出了select_for_update 的以下用法示例:
from django.db import transaction
entries = Entry.objects.select_for_update().filter(author=request.user)
with transaction.atomic():
for entry in entries:
...
使用这种方法,可能会改变分配给entry 的模型实例并在这些实例上调用save。
在某些情况下,我更喜欢下面的替代方法,但我不确定它是否适用于select_for_update。
with transaction.atomic():
Entry.objects.select_for_update().filter(author=request.user).update(foo="bar", wobble="wibble")
文档声明锁是在评估查询集时创建的,所以我怀疑update 方法是否可行。据我所知update 只是执行UPDATE ... WHERE 查询,之前没有SELECT。但是,如果对 Django ORM 的这方面更有经验的人能证实这一点,我将不胜感激。
第二个问题是,如果对锁定的行进行单个 UPDATE 查询,锁定是否甚至会增加任何针对竞争条件的保护。 (我进入这个思路是因为我正在重构在更新单行的两列的值时使用锁的代码。)
【问题讨论】:
-
如果您更喜欢不同的方法,您是否考虑过bulk_update?
-
@markwalker_ 谢谢,这是个好建议。我想
bulk_update可能会更有效,因为它只使用一个 UPDATE 查询而不是每行一个。 -
用例我正在考虑更新单行并使用 select_for_update 锁定它的方法。在我写这个问题的时候,我没有意识到
qs.get(foo="bar")会导致基于qs的查询集被评估,这意味着至少我不必遍历包含单个结果的查询集。跨度>
标签: python django postgresql locking django-orm