sql >> Databasteknik >  >> RDS >> PostgreSQL

Vilka specifika undantag representerar ett serialiseringsfel när Django använder serialiserbar transaktionsisoleringsnivå med postgresql?

Hmm, bra fråga. Dokumentationen innebär att det lämpliga undantaget skulle vara ett TransactionManagementError :

Men källkoden ger en stark ledtråd om att det inte är:

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

Observera att detta är ett Programmeringsfel , som verkligen används för att indikera programmeringsfel (dvs. "används felaktigt").

Om vi ​​tittar på dokumentationen för psycopg (Python-adaptern som används för PostgreSQL-stöd) ser vi att den kommer att höja en psycopg2.extensions.TransactionRollbackError :

Men vad gör Django med det? Tja, som dokumenterat här , lindar den standard Python DB API 2.0 undantagen i Django-ekvivalenter och ställer in __cause__ tillskriva det ursprungliga undantaget. Så följande är förmodligen den mest specifika kontrollen du kan göra:

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

Beroende på felinformationen som avslöjas av PostgreSQL (tillgänglig via e .__cause__.diag ) kan det vara möjligt att skriva ett ännu mer specifikt test.

I allmänhet anger Python DB API 2.0-dokumentationen att OperationalError är verkligen den korrekta undantagstypen för transaktionsproblem, så att fånga upp det skulle förhoppningsvis vara en någorlunda effektiv databasagnostisk lösning.




  1. Java får det automatiska ökningsnumret för den aktuella infogade raden, för att använda den för en annan fråga?

  2. Hur dumpar man mysql-tabellstruktur utan data med en SQL-fråga?

  3. Oracle 12.2 - Ersättning av NOPARTITION-funktionen

  4. Är mysql_real_escape_string() trasig?