为什么选择更新在 django mysql 中不起作用?

Kra*_* Li 1 mysql django transactions

我有一张如下表

select id, name from node;
+----+------+
| id | name |
+----+------+
|  5 | na   |
+----+------+
Run Code Online (Sandbox Code Playgroud)

然后定义下面的函数

>>> def foo_with_sfu(seconds):
...     with transaction.atomic():
...         node = Node.objects.select_for_update().filter(pk=5)
...         time.sleep(seconds)
...         node = Node.objects.get(pk=5)
...         print(node.name)
... 
Run Code Online (Sandbox Code Playgroud)

我希望 select_for_update 会锁定行 pk=5 所以如果我打开另一个控制台在 time.sleep 期间更改 node.name,更改操作将被阻止。

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

似乎选择更新没有锁定行。为什么?

Kev*_*nry 5

您的select_for_update()查询永远不会被评估,因此永远不会在数据库上执行锁定。请参阅有关何时以及如何评估查询集的文档

如果您只是将调用包装在查询集评估函数中,您的测试应该可以工作。例如:

with transaction.atomic():
    node = list(Node.objects.select_for_update().filter(pk=5))
Run Code Online (Sandbox Code Playgroud)