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

Isolamento delle transazioni in PostgreSQL

PostgreSQL è dotato di funzionalità solide e testate nel tempo che ti consentono di definire esattamente cosa dovrebbe accadere quando più client tentano di aggiornare gli stessi dati contemporaneamente. Uno di questi è il livello di isolamento delle transazioni.

Continua a leggere per saperne di più su come funziona l'isolamento delle transazioni in PostgreSQL.

Transazioni e livello di isolamento

Le transazioni sono il modo fondamentale per mutare i dati in un RDBMS. I moderni RDBMS consentono l'esecuzione simultanea di più di una transazione e, di conseguenza, sono dotati di una varietà di strumenti, alcuni standard, altri specifici di RDBMS, per consentire agli sviluppatori di applicazioni di specificare come le loro transazioni devono o non devono interagire con altre transazioni.

I livelli di isolamento delle transazioni e i blocchi pessimistici sono due di questi strumenti. Sebbene siano necessari per l'integrità e le prestazioni dei dati, sfortunatamente non sono intuitivi da comprendere o utilizzare.

Il livello di isolamento di una transazione, in PostgreSQL, può essere uno di:

  • Leggi Impegno
  • Lettura ripetibile
  • Serializzabile

Ogni transazione ha il suo livello di isolamento impostato su uno di questi quando viene creata. Il livello predefinito è "read commit".

Si noti che lo standard SQL definisce anche "read uncommitted", che non è supportato in Postgres. Devi usare il livello più vicino e più alto di "read commit".

Vediamo cosa significano questi livelli.

Lettura impegnata

Cosa succede quando una transazione (non completata) inserisce righe in una tabella e l'altra transazione (anch'essa non completata) tenta di leggere tutte le righe della tabella? Se la seconda transazione è in grado di vedere le righe inserite dalla prima, quella read è chiamata lettura sporca – perché la prima transazione può essere ripristinata e la seconda avrebbe letto righe "fantasma" che non sono mai esistite.

La lettura impegnata il livello di isolamento garantisce che le letture sporche non accadano mai. Ecco un esempio:

Come puoi vedere, la seconda transazione non è stata in grado di leggere i dati della prima transazione non ancora impegnati. In PostgreSQL, non è possibile abbassare il livello di isolamento al di sotto di questo livello in modo che siano consentite letture sporche.

Lettura ripetibile

Ancora un altro problema è quello delle letture non ripetibili. Questi si verificano quando una transazione legge una riga, quindi la rilegge un po' più tardi, ma ottiene un risultato diverso, perché la riga è stata aggiornata nel frattempo da un'altra transazione. La lettura è diventata non ripetibile , come mostrato in questo esempio:

Per risolvere questo problema, impostare il livello di isolamento della transazione su "lettura ripetibile". PostgreSQL si assicurerà quindi che anche la seconda (o qualsiasi) lettura restituisca lo stesso risultato della prima lettura. Ecco lo stesso scenario al livello di isolamento aggiornato:

Si noti che il livello di isolamento è stato specificato insieme all'istruzione BEGIN. È anche possibile specificarlo a livello di connessione (come parametro di connessione), come parametro di configurazione (default_transaction_isolation )e utilizzando l'istruzione SET TRANSACTION.

Serializzabile

Il livello di isolamento successivo risolve il problema degli aggiornamenti persi . Gli aggiornamenti eseguiti in una transazione possono essere "persi" o sovrascritti da un'altra transazione eseguita contemporaneamente, come mostrato qui:

Qui i blocchi UPDATE della seconda transazione, perché PostgreSQL blocca per impedire un altro aggiornamento fino al termine della prima transazione. Tuttavia, la modifica della prima transazione va persa, perché la seconda ha "sovrascritto" la riga.

Se questo tipo di comportamento non è accettabile, puoi aggiornare il livello di isolamento a serializzabile:

A questo livello, il commit della seconda transazione non riesce. Le azioni della seconda transazione erano basate su fatti che erano stati resi non validi nel momento in cui stava per commettere.

Sebbene la serializzazione offra il massimo livello di sicurezza, significa anche che l'applicazione deve rilevare tali errori di commit e riprovare l'intera transazione.