gpt4 book ai didi

mysql - select_for_update 在解锁后是否会看到另一个 select_for_update 事务添加的行?

转载 作者:行者123 更新时间:2023-11-29 09:49:38 26 4
gpt4 key购买 nike

我想创建一个模型,其 ID 等于该模型当前最大 ID 加一(如自动增量)。我正在考虑使用 select_for_update 执行此操作,以确保当前最大 ID 不存在竞争条件,如下所示:

with transaction.atomic():
greatest_id = MyModel.objects.select_for_update().order_by('id').last().id
MyModel.objects.create(id=greatest_id + 1)

但是我想知道,如果两个进程尝试同时运行这个,一旦第二个进程解除阻塞,它会看到第一个进程插入的新的最大ID,还是仍然会看到旧的最大ID?

例如,假设当前最大的ID是10。两个进程去创建一个新模型。第一个锁定 ID 10。然后第二个锁定,因为 10 被锁定。第一个插入 11 并解锁 10。然后,第二个解锁,现在它会看到第一个插入的 11 是最大的,还是仍然会看到 10,因为这是它阻塞的行?

在 select_for_update docs ,它说:

Usually, if another transaction has already acquired a lock on one of the selected rows, the query will block until the lock is released.

因此,对于我的示例,我认为这意味着第二个进程在解锁并获得 11 后将重新运行最大 ID 的查询。但我不确定我的解释是否正确。

注意:我使用 MySQL 作为数据库。

最佳答案

不,我认为这行不通。

首先,请注意,您绝对应该检查您正在使用的数据库的文档,因为数据库之间存在许多微妙的差异,这些差异没有在 Django 文档中捕获。

使用PostgreSQL documentation作为指导,问题在于,在默认的 READ COMMITTED 隔离级别下,被阻止的查询将不会重新运行。当第一个事务提交时,被阻止的事务将能够看到该行的更改,但无法看到已添加的新行。

It is possible for an updating command to see an inconsistent snapshot: it can see the effects of concurrent updating commands on the same rows it is trying to update, but it does not see effects of those commands on other rows in the database.

因此 10 就是将返回的内容。

关于mysql - select_for_update 在解锁后是否会看到另一个 select_for_update 事务添加的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55033473/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com