Хм, добър въпрос. Документацията предполага, че подходящото изключение би било TransactionManagementErrorкод>
:
Обаче изходният код дава силна представа, че не е:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Имайте предвид, че това е ProgrammingError
, което наистина се използва за указване на програмна грешка (т.е. „използвано неправилно“).
Ако погледнем документацията за psycopg (адаптерът на Python, използван за поддръжка на PostgreSQL), ще видим, че той ще предизвика psycopg2.extensions.TransactionRollbackError
:
Но какво прави Джанго с това? Е, както документирано тук
, той обвива стандартните Python DB API 2.0 изключения в Django еквиваленти и задава __cause__
атрибут към оригиналното изключение. Така че следното вероятно е най-конкретната проверка, която можете да направите:
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
В зависимост от подробностите за грешката, изложени от PostgreSQL (достъпни чрез e .__cause__.diag
) може да е възможно да напишете още по-специфичен тест.
Като цяло обаче документацията на Python DB API 2.0 посочва, че OperationalError
наистина е правилният тип изключение за проблеми с транзакциите, така че да се надяваме, че улавянето ще бъде сравнително ефективно решение за агностик на база данни.