Hm, goede vraag. De documentatie houdt in dat de juiste uitzondering een TransactionManagementError
:
De broncode geeft een sterke aanwijzing dat het niet zo is:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Merk op dat dit een ProgrammingError
is
, wat inderdaad wordt gebruikt om een programmeerfout aan te geven (d.w.z. "onjuist gebruikt").
Als we kijken naar de documentatie voor psycopg (de Python-adapter die wordt gebruikt voor PostgreSQL-ondersteuning), zien we dat het een psycopg2.extensions.TransactionRollbackError
:
Maar wat doet Django daarmee? Nou, zoals hier gedocumenteerd
, het verpakt de standaard Python DB API 2.0-uitzonderingen in Django-equivalenten en stelt de __cause__
in toe te schrijven aan de oorspronkelijke uitzondering. Dus het volgende is waarschijnlijk de meest specifieke controle die u kunt uitvoeren:
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
Afhankelijk van de foutdetails die worden onthuld door PostgreSQL (beschikbaar via e .__oorzaak__.diag
) is het misschien mogelijk om een nog specifiekere test te schrijven.
Over het algemeen stelt de Python DB API 2.0-documentatie echter dat OperationalError
is inderdaad het juiste uitzonderingstype voor transactieproblemen, dus dat zou hopelijk een redelijk effectieve database-onafhankelijke oplossing zijn.