Hm, gute Frage. Die Dokumentation impliziert, dass die entsprechende Ausnahme ein TransactionManagementError
:
Allerdings ist der Quellcode gibt einen starken Hinweis darauf, dass dies nicht der Fall ist:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Beachten Sie, dass dies ein ProgrammingError
ist
, was tatsächlich verwendet wird, um Programmierfehler anzuzeigen (d. h. "unsachgemäß verwendet").
Wenn wir uns die Dokumentation für psycopg (den für die PostgreSQL-Unterstützung verwendeten Python-Adapter) ansehen, sehen wir, dass es ein psycopg2.extensions.TransactionRollbackError
:
Aber was macht Django damit? Nun, wie hier dokumentiert
, umschließt es die standardmäßigen Python DB API 2.0-Ausnahmen in Django-Entsprechungen und legt den __cause__
fest Attribut zur ursprünglichen Ausnahme. Das Folgende ist wahrscheinlich die spezifischste Überprüfung, die Sie durchführen können:
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
Abhängig von den Fehlerdetails, die von PostgreSQL (verfügbar über e .__cause__.diag
) ist es möglich, einen noch spezifischeren Test zu schreiben.
Im Allgemeinen heißt es in der Python DB API 2.0-Dokumentation jedoch, dass OperationalError
ist in der Tat der richtige Ausnahmetyp für Transaktionsprobleme, also wäre das Abfangen hoffentlich eine einigermaßen effektive datenbankunabhängige Lösung.