PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Welche spezifischen Ausnahmen stellen einen Serialisierungsfehler dar, wenn Django die Isolationsstufe für serialisierbare Transaktionen mit postgresql verwendet?

Hm, gute Frage. Die Dokumentation impliziert, dass die entsprechende Ausnahme ein TransactionManagementError :

Allerdings ist der Quellcode gibt einen starken Hinweis darauf, dass dies nicht der Fall ist:

class TransactionManagementError(ProgrammingError):
    """Transaction management is used improperly."""
    pass

Beachten Sie, dass dies ein ProgrammingError ist , was tatsächlich verwendet wird, um Programmierfehler anzuzeigen (d. h. "unsachgemäß verwendet").

Wenn wir uns die Dokumentation für psycopg (den für die PostgreSQL-Unterstützung verwendeten Python-Adapter) ansehen, sehen wir, dass es ein psycopg2.extensions.TransactionRollbackError :

Aber was macht Django damit? Nun, wie hier dokumentiert , umschließt es die standardmäßigen Python DB API 2.0-Ausnahmen in Django-Entsprechungen und legt den __cause__ fest Attribut zur ursprünglichen Ausnahme. Das Folgende ist wahrscheinlich die spezifischste Überprüfung, die Sie durchführen können:

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

Abhängig von den Fehlerdetails, die von PostgreSQL (verfügbar über e .__cause__.diag ) ist es möglich, einen noch spezifischeren Test zu schreiben.

Im Allgemeinen heißt es in der Python DB API 2.0-Dokumentation jedoch, dass OperationalError ist in der Tat der richtige Ausnahmetyp für Transaktionsprobleme, also wäre das Abfangen hoffentlich eine einigermaßen effektive datenbankunabhängige Lösung.