除已知场景外,Django中select_for_update()不生效但print(qs)生效的其他情况
Django中select_for_update()不生效但print(qs)后生效的其他场景
模型定义
# "store/models.py" from django.db import models class Person(models.Model): name = models.CharField(max_length=30)
已知案例
案例1:QuerySet.update()链式调用
- 直接链式调用:
Person.objects.select_for_update().update(name="Tom")仅执行UPDATE语句,无SELECT FOR UPDATE锁查询。 - 拆分并加入print:
此时会先后执行SELECT FOR UPDATE和UPDATE两种查询。qs = Person.objects.select_for_update() print(qs) # 触发QuerySet求值,执行SELECT FOR UPDATE qs.update(name="Tom") # 执行UPDATE语句 - 与对象save()结合:先通过select_for_update()获取对象,再调用save(),会正常执行SELECT FOR UPDATE和UPDATE查询。
案例2:QuerySet.delete()链式调用
- 直接链式调用:
Person.objects.select_for_update().delete()仅执行DELETE语句,无SELECT FOR UPDATE锁查询。 - 拆分并加入print:
此时会先后执行SELECT FOR UPDATE和DELETE两种查询。qs = Person.objects.select_for_update() print(qs) # 触发QuerySet求值,执行SELECT FOR UPDATE qs.delete() # 执行DELETE语句 - 与对象delete()结合:先通过select_for_update()获取对象,再调用delete(),会正常执行SELECT FOR UPDATE和DELETE查询。
其他符合条件的场景
以下场景中,直接链式调用select_for_update()与对应QuerySet方法时,select_for_update()不会生效;但提前通过print(qs)触发QuerySet求值后,会先执行SELECT FOR UPDATE锁查询,再执行目标操作:
QuerySet.bulk_create()批量插入
- 直接调用:
Person.objects.select_for_update().bulk_create([Person(name="Alice"), Person(name="Bob")])仅执行批量INSERT语句,无锁查询。 - 拆分加print后:先执行SELECT FOR UPDATE锁定匹配行,再执行批量插入。
- 直接调用:
QuerySet.bulk_update()批量更新
- 直接调用:
仅执行批量UPDATE语句,无锁查询。persons = Person.objects.filter(name__startswith="A") for p in persons: p.name = p.name + "_updated" Person.objects.select_for_update().bulk_update(persons, ["name"]) - 拆分加print后:先执行SELECT FOR UPDATE锁定匹配行,再执行批量更新。
- 直接调用:
QuerySet.exists()存在性检查
- 直接调用:
Person.objects.select_for_update().exists()仅执行EXISTS查询,不会锁定任何行。 - 拆分加print后:先执行SELECT FOR UPDATE锁定匹配行,再执行EXISTS检查。
- 直接调用:
QuerySet.count()统计数量
- 直接调用:
Person.objects.select_for_update().count()仅执行COUNT聚合查询,无锁查询。 - 拆分加print后:先执行SELECT FOR UPDATE锁定匹配行,再统计行数。
- 直接调用:
QuerySet.aggregate()聚合计算
- 直接调用:
Person.objects.select_for_update().aggregate(total=Count('id'))仅执行聚合查询,无锁查询。 - 拆分加print后:先执行SELECT FOR UPDATE锁定匹配行,再执行聚合计算。
- 直接调用:
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

