Hmm, dobrá otázka. Z dokumentace vyplývá, že příslušnou výjimkou by byla TransactionManagementError
:
Nicméně zdrojový kód dává silné vodítko, že tomu tak není:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Upozorňujeme, že toto je ProgrammingError
, který se skutečně používá k označení chyby programátoru (tj. "použito nesprávně").
Pokud se podíváme na dokumentaci pro psycopg (adaptér Python používaný pro podporu PostgreSQL), uvidíme, že vyvolá psycopg2.extensions.TransactionRollbackError
:
Ale co s tím Django dělá? Jak zde zdokumentováno
, zabalí standardní výjimky Python DB API 2.0 do ekvivalentů Django a nastaví __cause__
atribut k původní výjimce. Takže následující je pravděpodobně nejkonkrétnější kontrola, kterou můžete provést:
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
V závislosti na podrobnostech o chybě odhalených PostgreSQL (dostupné prostřednictvím e .__cause__.diag
) může být možné napsat ještě konkrétnější test.
Obecně však dokumentace Python DB API 2.0 uvádí, že OperationalError
je skutečně správným typem výjimky pro problémy s transakcemi, takže jeho zachycení by bylo, doufejme, přiměřeně efektivním řešením bez databáze.