为什么选择更新在Django MySQL中不起作用?

时间:2018-09-28 02:58:17

标签: mysql django transactions

我有一个如下表

select id, name from node;
+----+------+
| id | name |
+----+------+
|  5 | na   |
+----+------+

然后在下面定义功能

>>> def foo_with_sfu(seconds):
...     with transaction.atomic():
...         node = Node.objects.select_for_update().filter(pk=5)[0]
...         print(node.name)
...         time.sleep(seconds)
...         node = Node.objects.get(pk=5)
...         print(node.name)
... 

我希望select_for_update将锁定行pk = 5,所以如果我打开另一个控制台在time.sleep期间更改node.name,则更改操作将被阻止,并且上述函数的两次打印将始终返回一致的结果

但是实际上,当我运行该函数并在time.sleep期间在另一个控制台中运行update sql时,更新未被阻止。

似乎选择更新不会锁定该行。为什么?

1 个答案:

答案 0 :(得分:1)

您的select_for_update()查询从不评估,因此该锁定永远不会在数据库上执行。有关何时以及如何评估查询集的信息,请参见the documentation

如果仅将调用包装在queryset-evaluating函数中,则测试应该可以进行。例如:

with transaction.atomic():
    node = list(Node.objects.select_for_update().filter(pk=5))