Hmm, câu hỏi hay. Tài liệu ngụ ý rằng ngoại lệ thích hợp sẽ là TransactionManagementError
:
Tuy nhiên, mã nguồn đưa ra một manh mối chắc chắn rằng nó không phải là:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Lưu ý rằng đây là ProgrammingError
, thực sự được sử dụng để chỉ ra lỗi của lập trình viên (tức là "được sử dụng không đúng cách").
Nếu chúng ta xem tài liệu về psycopg (bộ điều hợp Python được sử dụng để hỗ trợ PostgreSQL), chúng ta thấy rằng nó sẽ tăng psycopg2.extensions.TransactionRollbackError
:
Nhưng Django làm gì với điều đó? Vâng, như được ghi lại ở đây
, nó bao bọc các ngoại lệ Python DB API 2.0 tiêu chuẩn trong các phiên bản tương đương của Django và đặt __cause__
thuộc tính cho ngoại lệ ban đầu. Vì vậy, sau đây có lẽ là cách kiểm tra cụ thể nhất mà bạn có thể thực hiện:
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
Tùy thuộc vào chi tiết lỗi do PostgreSQL hiển thị (có sẵn qua e .__ nguyên nhân __. chẩn đoán
) có thể viết một bài kiểm tra cụ thể hơn.
Tuy nhiên, nói chung, tài liệu Python DB API 2.0 nói rằng OperationalError
thực sự là loại ngoại lệ chính xác cho các vấn đề giao dịch, vì vậy việc nắm bắt đó hy vọng sẽ là một giải pháp bất khả tri cơ sở dữ liệu hiệu quả hợp lý.