sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvilke specifikke undtagelser repræsenterer en serialiseringsfejl, når Django bruger serialiserbart transaktionsisoleringsniveau med postgresql?

Hmm, godt spørgsmål. Dokumentationen indebærer, at den passende undtagelse ville være en TransactionManagementError :

Men kildekoden giver et stærkt fingerpeg om, at det ikke er:

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

Bemærk, at dette er en Programmeringsfejl , som faktisk bruges til at angive programmeringsfejl (dvs. "brugt forkert").

Hvis vi ser på dokumentationen for psycopg (Python-adapteren, der bruges til PostgreSQL-understøttelse), ser vi, at den vil rejse en psycopg2.extensions.TransactionRollbackError :

Men hvad gør Django med det? Nå, som dokumenteret her , indpakker den standard Python DB API 2.0 undtagelserne i Django-ækvivalenter og indstiller __cause__ tilskrives den oprindelige undtagelse. Så følgende er nok den mest specifikke kontrol, du kan foretage:

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

Afhængigt af fejldetaljerne afsløret af PostgreSQL (tilgængelig via e .__cause__.diag ) kan det være muligt at skrive en endnu mere specifik test.

Generelt siger Python DB API 2.0-dokumentationen dog, at OperationalError er faktisk den korrekte undtagelsestype for transaktionsproblemer, så at fange det ville forhåbentlig være en rimelig effektiv databaseagnostisk løsning.




  1. forhindrer flere samtidige forespørgsler med php/mysql live-søgning

  2. Vælg flere id'er fra en tabel

  3. Er der en tilsvarende for SQL Servers @@-fejl i MySQL

  4. Brug Excel 2010 til at læse/skrive til en SQL Server 2008-database ved hjælp af lagrede procedurer