根据Django文档:
通常,如果另一个事务已经对其中一个选定行获取了锁定,则查询将一直阻塞,直到锁定被释放。如果这不是您想要的行为,请调用select_for_update(nowait = True)。这将使呼叫无阻塞。如果另一个事务已经获取了冲突的锁,则在评估查询集时将引发DatabaseError。
我正在尝试这个,但发现了一个奇怪的行为。同时运行下面的代码并不会引发错误,但会以阻塞方式工作。
def test4():
with transaction.atomic():
WorkflowCallContact.objects.select_for_update(nowait=True).filter(id__in=[1,2,3,4]).update(number="22222")
time.sleep(10)
list(WorkflowCallContact.objects.filter(id__in=[1,2,3,4]))
为了测试,我只是打开shell并且并行调用相同的函数。但是,由于DatabaseError
而不是在第二次通话中抛出nowait=True
,呼叫将被阻止10秒。
数据库我正在使用:postgres Django版本:1.9
答案 0 :(得分:0)
select_for_update()
和 update()
不能链接。您必须强制对 QuerySet 进行评估,例如将其转换为 list():
with transaction.atomic():
list(WorkflowCallContact.objects.select_for_update(nowait=True).filter(id__in=[1,2,3,4]))
WorkflowCallContact.objects.filter(id__in=[1,2,3,4]).update(number="22222")