PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Quais exceções específicas representam uma falha de serialização quando o Django está usando o nível de isolamento de transação serializável com postgresql?


Hum, boa pergunta. A documentação implica que a exceção apropriada seria um TransactionManagementError :

No entanto, o código-fonte dá uma forte pista de que não é:
class TransactionManagementError(ProgrammingError):
    """Transaction management is used improperly."""
    pass

Observe que este é um ProgrammingError , que de fato é usado para indicar erro do programador (ou seja, "usado incorretamente").

Se examinarmos a documentação do psycopg (o adaptador Python usado para suporte ao PostgreSQL), veremos que ele gerará um psycopg2.extensions.TransactionRollbackError :

Mas o que o Django faz com isso? Bem, como documentado aqui , ele envolve as exceções padrão do Python DB API 2.0 em equivalentes do Django e define o __cause__ atribuir à exceção original. Portanto, o seguinte é provavelmente a verificação mais específica que você pode fazer:
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

Dependendo dos detalhes do erro expostos pelo PostgreSQL (disponível em e .__cause__.diag ) pode ser possível escrever um teste ainda mais específico.

Geralmente, porém, a documentação do Python DB API 2.0 afirma que OperationalError é, de fato, o tipo de exceção correto para problemas de transação, portanto, capturá-lo esperançosamente seria uma solução agnóstica de banco de dados razoavelmente eficaz.