Hmm, godt spørgsmål. Dokumentationen indebærer, at den passende undtagelse ville være en TransactionManagementError
:
Men kildekoden giver et stærkt fingerpeg om, at det ikke er:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Bemærk, at dette er en Programmeringsfejl
, som faktisk bruges til at angive programmeringsfejl (dvs. "brugt forkert").
Hvis vi ser på dokumentationen for psycopg (Python-adapteren, der bruges til PostgreSQL-understøttelse), ser vi, at den vil rejse en psycopg2.extensions.TransactionRollbackError
:
Men hvad gør Django med det? Nå, som dokumenteret her
, indpakker den standard Python DB API 2.0 undtagelserne i Django-ækvivalenter og indstiller __cause__
tilskrives den oprindelige undtagelse. Så følgende er nok den mest specifikke kontrol, du kan foretage:
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
Afhængigt af fejldetaljerne afsløret af PostgreSQL (tilgængelig via e .__cause__.diag
) kan det være muligt at skrive en endnu mere specifik test.
Generelt siger Python DB API 2.0-dokumentationen dog, at OperationalError
er faktisk den korrekte undtagelsestype for transaktionsproblemer, så at fange det ville forhåbentlig være en rimelig effektiv databaseagnostisk løsning.