gpt4 book ai didi

django - 当 Django 在 postgresql 中使用可序列化事务隔离级别时,哪些特定异常表示序列化失败?

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

有时需要为 Django 中的数据库操作使用比默认“已提交读取”更高的隔离级别。 The docs warn那:

Under higher isolation levels, your application should be prepared to handle exceptions raised on serialization failures.

但是哪些特定异常表示序列化失败,哪些是查询或事务的其他问题?

序列化失败后的简单重试机制可能如下所示:

for retries in range(0, 3):
try:
with transaction.atomic():
MyModel.objects.update(foo='bar')
except StuffHappened:
continue
else:
break

哪些特定异常应该替换 StuffHappened 以便只有序列化失败而不是其他异常导致重试?

Django 有多种 Database ExceptionsTransaction Exceptions .可能其中一个/一些代表序列化失败?

为此,我对 postgresql 特别感兴趣。

最佳答案

嗯,问得好。该文档暗示适当的异常将是 TransactionManagementError :

TransactionManagementError is raised for any and all problems related to database transactions.

然而,source code给出了一个强有力的线索,表明它不是:

class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass

注意这是一个ProgrammingError ,它确实用于指示程序员错误(即“使用不当”)。

如果我们查看 psycopg(用于支持 PostgreSQL 的 Python 适配器)的文档,我们会发现它会引发 psycopg2.extensions.TransactionRollbackError。 :

exception psycopg2.extensions.TransactionRollbackError (subclasses OperationalError)

Error causing transaction rollback (deadlocks, serialization failures, etc).

但是 Django 用它做什么呢?嗯,作为documented here ,它将标准 Python DB API 2.0 异常包装在 Django 等效项中,并将 __cause__ 属性设置为原始异常。因此,以下可能是您可以进行的最具体的检查:

from django.db import OperationalError
from psycopg2.extensions import TransactionRollbackError

for retries in range(0, 3):
try:
with transaction.atomic():
MyModel.objects.update(foo='bar')
except OperationalError as e:
if e.__cause__.__class__ == TransactionRollbackError:
continue
else:
raise
else:
break

根据 PostgreSQL 公开的错误详细信息(可通过 e.__cause__.diag 获得),可以编写更具体的测试。

不过,一般来说,Python DB API 2.0 文档指出 OperationalError确实是事务问题的正确异常类型,因此捕获它有望成为一个合理有效的与数据库无关的解决方案。

关于django - 当 Django 在 postgresql 中使用可序列化事务隔离级别时,哪些特定异常表示序列化失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52434925/

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