gpt4 book ai didi

database - 使用事务从数据库中安全删除 Django 模型

转载 作者:行者123 更新时间:2023-11-29 14:07:55 25 4
gpt4 key购买 nike

在我的 Django 应用程序中,我有从数据库中删除模型的单个实例的代码。两个并发请求有可能同时尝试删除同一个模型。在这种情况下,我希望一个请求成功而另一个请求失败。我该怎么做?

问题是当使用delete() 删除实例时,Django 不会返回任何关于命令是否成功的信息。此代码说明了问题:

b0 = Book.objects.get(id=1)
b1 = Book.objects.get(id=1)
b0.delete()
b1.delete()

这两个 delete() 命令中只有一个真正删除了对象,但我不知道是哪一个。不会抛出任何异常,也不会返回任何指示命令成功的内容。在纯 SQL 中,该命令将返回删除的行数,如果值为 0,我就知道我的删除失败了。

我正在使用默认的 Read Commited 隔离级别的 PostgreSQL。我对这个级别的理解是每个命令(SELECT、DELETE 等)看到数据库的快照,但下一个命令可能看到数据库的不同快照。我相信这意味着我不能做这样的事情:

# I believe this wont work
@commit_on_success
def view(request):
try:
book = Book.objects.get(id=1)
# Possibility that the instance is deleted by the other request
# before we get to the next delete()
book.delete()
except ObjectDoesntExist:
# Already been deleted

有什么想法吗?

最佳答案

您可以使用 QuerySet.delete 而不是 Model.delete 将约束直接放入 SQL DELETE 语句中:

Book.objects.filter(pk=1).delete()

这根本不会发出 SELECT 查询,只是类似于:

DELETE FROM Book WHERE id=1;

它处理两个并发请求同时删除同一条记录的竞争条件,但它不会让您知道您的删除是否先到达那里。为此,您必须获取原始光标(django lets you do),.execute() 上面的 DELETE 自己,然后拿起光标的 rowcount。属性,如果您最终没有删除任何内容,该属性将为 0。

关于database - 使用事务从数据库中安全删除 Django 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4762956/

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