sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Qué excepciones específicas representan una falla de serialización cuando Django usa un nivel de aislamiento de transacciones serializable con postgresql?

Mmm, buena pregunta. La documentación implica que la excepción apropiada sería un TransactionManagementError :

Sin embargo, el código fuente da una fuerte pista de que no lo es:

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

Tenga en cuenta que este es un ProgrammingError , que de hecho se usa para indicar un error del programador (es decir, "usado incorrectamente").

Si observamos la documentación de psycopg (el adaptador de Python utilizado para la compatibilidad con PostgreSQL), vemos que generará un psycopg2.extensions.TransactionRollbackError :

Pero, ¿qué hace Django con eso? Bueno, como documentado aquí , envuelve las excepciones estándar de Python DB API 2.0 en equivalentes de Django y establece el __cause__ atribuir a la excepción original. Entonces, la siguiente es probablemente la verificación más específica que puede hacer:

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

Dependiendo de los detalles del error expuestos por PostgreSQL (disponible a través de e.__cause__.diag ) es posible escribir una prueba aún más específica.

Sin embargo, en general, la documentación de Python DB API 2.0 establece que OperationalError es, de hecho, el tipo de excepción correcto para los problemas de transacciones, por lo que, con suerte, sería una solución independiente de la base de datos razonablemente eficaz.