Hmm, dobre pytanie. Dokumentacja sugeruje, że odpowiednim wyjątkiem byłby TransactionManagementError
:
Jednak kod źródłowy daje mocną wskazówkę, że tak nie jest:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Zauważ, że jest to Błąd programowania
, który rzeczywiście jest używany do wskazania błędu programisty (tj. "niewłaściwie użyty").
Jeśli spojrzymy na dokumentację psycopg (adaptera Pythona używanego do obsługi PostgreSQL), zobaczymy, że podniesie on psycopg2.extensions.TransactionRollbackError
:
Ale co Django z tym robi? Cóż, jak udokumentowano tutaj
, opakowuje standardowe wyjątki Python DB API 2.0 w odpowiedniki Django i ustawia __cause__
atrybut do oryginalnego wyjątku. Oto prawdopodobnie najbardziej szczegółowa kontrola, jaką możesz wykonać:
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
W zależności od szczegółów błędu ujawnionych przez PostgreSQL (dostępne za pośrednictwem e .__przyczyna__.diag
) możliwe jest napisanie jeszcze bardziej szczegółowego testu.
Ogólnie jednak dokumentacja Python DB API 2.0 stwierdza, że OperationalError
jest rzeczywiście właściwym typem wyjątku dla problemów z transakcjami, więc przechwycenie tego, miejmy nadzieję, byłoby rozsądnie skutecznym rozwiązaniem niezależnym od bazy danych.