代码之家  ›  专栏  ›  技术社区  ›  user85461

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

  •  3
  • user85461  · 技术社区  · 7 年前

    有时,对于Django中的数据库操作,最好使用比默认的“read committed”更高的隔离级别。 The docs warn 那就是:

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

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

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

    应替换哪些特定例外 StuffHappened

    Django有各种各样的 Database Exceptions Transaction Exceptions . 其中一个/一些可能表示序列化失败?

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

    1 回复  |  直到 7 年前
        1
  •  5
  •   Kevin Christopher Henry    6 年前

    嗯,问得好。文件表明,适当的例外情况是 TransactionManagementError

    事务管理错误 针对与数据库事务相关的所有问题提出。

    source code 提供了一个强有力的线索,它不是:

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

    ProgrammingError ,这确实是用来表示程序员错误(即“使用不当”)。

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

    心理学2。extensions.TransactionRollbackError (子类) OperationalError

    导致事务回滚的错误(死锁、序列化失败等)。

    documented here ,它将标准pythondbapi2.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
    

    e.__cause__.diag )也许可以编写一个更具体的测试。

    不过,一般来说,pythondbapi2.0文档说明 OperationalError