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.