为什么“select_for_update()”不能在Django中使用MySQL?

unftdfkk  于 2022-12-26  发布在  Mysql
关注(0)|答案(2)|浏览(135)

我有一个表如下:

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)
...         time.sleep(seconds)
...         node = Node.objects.get(pk=5)
...         print(node.name)
...

我希望select_for_update将锁定行pk=5,这样,如果我在time.sleep期间打开另一个控制台更改node.name,更改操作将被阻止。
但实际上,当我运行该函数时,并在另一个控制台中运行update sql(在.sleep期间),更新没有被阻止。
更新的选择似乎没有锁定行。为什么?

gcuhipw9

gcuhipw91#

您的select_for_update()查询永远不会被求值,因此锁永远不会在数据库上执行。有关何时以及如何求值查询集的信息,请参阅文档。
如果你只是简单地将调用 Package 在一个查询集求值函数中,那么你的测试应该可以工作。

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

tuwxkamq2#

要运行SELECT FOR UPDATE,您需要将print(node)放在**select_for_update()*之后,如下所示。 您也可以将bool(node)len(node)list(node)放在print(node)之后:

node = Node.objects.select_for_update().filter(pk=5)
print(node) # bool(node), len(node) or list(node) is also fine

你可以在Django中看到my question and answerselect_for_update()的更多解释:

相关问题