Hmm, pertanyaan yang bagus. Dokumentasi menyiratkan bahwa pengecualian yang sesuai adalah TransactionManagementError
:
Namun, kode sumber memberikan petunjuk kuat bahwa itu bukan:
class TransactionManagementError(ProgrammingError):
"""Transaction management is used improperly."""
pass
Perhatikan bahwa ini adalah ProgrammingError
, yang memang digunakan untuk menunjukkan kesalahan pemrogram (yaitu "digunakan dengan tidak semestinya").
Jika kita melihat dokumentasi untuk psycopg (adaptor Python yang digunakan untuk dukungan PostgreSQL) kita melihat bahwa itu akan memunculkan psycopg2.extensions.TransactionRollbackError
:
Tapi apa yang Django lakukan dengan itu? Nah, seperti yang didokumentasikan di sini
, ini membungkus pengecualian standar Python DB API 2.0 dalam padanan Django, dan menyetel __cause__
atribut ke pengecualian asli. Jadi, berikut ini mungkin pemeriksaan paling spesifik yang dapat Anda lakukan:
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
Bergantung pada detail kesalahan yang diekspos oleh PostgreSQL (tersedia melalui e.__cause__.diag
) dimungkinkan untuk menulis tes yang lebih spesifik.
Namun, secara umum, dokumentasi Python DB API 2.0 menyatakan bahwa OperationalError
memang jenis pengecualian yang benar untuk masalah transaksi, jadi mudah-mudahan akan menjadi solusi agnostik basis data yang cukup efektif.