CodeGym /Corsi /SQL SELF /Introduzione ai livelli di isolamento delle transazioni

Introduzione ai livelli di isolamento delle transazioni

SQL SELF
Livello 39 , Lezione 4
Disponibile

Immagina di lavorare in un bar, dove un cameriere controlla la scorta di torte in cucina e un altro sta compilando un ordine di torta per un nuovo cliente. In un mondo perfetto dovrebbero lavorare entrambi sugli stessi dati sul numero di torte, così da evitare errori tipo "doppia prenotazione". Ma nel mondo reale possono succedere casini dovuti all'esecuzione parallela delle operazioni.

Ecco tre grane principali che possono capitare:

  1. Dirty Read (lettura sporca): Una query vede modifiche fatte da un'altra, ma non ancora confermate. Se queste modifiche vengono annullate, la prima query rimane fregata, come uno studente al suo primo colloquio.

  2. Non-Repeatable Read (lettura non ripetibile): Una query legge due volte gli stessi dati, ma tra una lettura e l'altra qualcuno li cambia. È come andare in stazione, vedere l'orario dei treni, tornare dopo un minuto — e scoprire che il treno è stato cancellato. O che il tuo biglietto l'ha comprato qualcun altro mentre cercavi i soldi :)

  3. Phantom Read (lettura fantasma): Una query vede un sottoinsieme di righe, ma tra due esecuzioni qualcuno aggiunge nuove righe che cambiano il risultato. È come se la tua azienda avesse perso una gara d'appalto, e poi tutte le offerte tranne la tua e quella della moglie del sindaco venissero annullate.

Livelli di isolamento delle transazioni

Ora che conosciamo i problemi, è il momento di dare un'occhiata allo strumento che PostgreSQL offre per risolverli — i livelli di isolamento delle transazioni. È come mettere delle regole su come le transazioni parallele possono interagire. Più alto è il livello di isolamento, più garanzie hai che le transazioni non si pestino i piedi. Ma questo si paga con una "velocità di servizio" più bassa, cioè meno performance.

Livelli di isolamento in PostgreSQL

  1. Read Uncommitted (Lettura di dati non confermati):

    • Permette di leggere modifiche che non sono ancora state confermate (sì, questa è la lettura sporca in tutto il suo splendore).
    • In PostgreSQL questo livello in realtà è implementato come Read Committed, quindi non è supportato puro. PostgreSQL si rifiuta di implementarlo perché è troppo inaffidabile.
  2. Read Committed (Lettura di modifiche confermate):

    • Previene la lettura sporca.
    • La transazione vede solo i dati che sono stati confermati al momento dell'esecuzione del suo comando.
    • Però sono possibili Non-Repeatable Read e Phantom Read.
  3. Repeatable Read (Lettura ripetibile):

    • Garantisce che i dati che leggi restino invariati durante la transazione.
    • Previene la lettura sporca e la lettura non ripetibile.
    • Però le righe fantasma sono ancora possibili.
  4. Serializable (Serializzabile):

    • Garantisce che le transazioni vengano eseguite come se fossero una dopo l'altra, in sequenza.
    • Previene tutti e tre i problemi: lettura sporca, lettura non ripetibile e righe fantasma.
    • È il livello più rigoroso — e anche il più lento.

Perché l'isolamento delle transazioni è importante?

Ora immagina il database di un e-commerce, dove mille utenti cercano di fare un ordine nello stesso momento. Senza un livello di isolamento ben impostato rischi un sacco di conflitti: da prodotti "spariti" a ordini doppi.

Scegliere il giusto livello di isolamento aiuta a gestire la concorrenza tra le transazioni, trovando il giusto equilibrio tra performance e integrità dei dati. Per esempio:

  • Nei sistemi di analytics spesso si sceglie il livello minimo di isolamento (tipo Read Committed), perché la precisione dei dati non è sempre fondamentale.
  • Nei sistemi finanziari si preferisce il livello Serializable, per evitare errori nei calcoli o doppie operazioni.

Esempi di uso dei livelli di isolamento

  1. Read Committed

Questo livello assicura che non leggerai mai dati che potrebbero essere stati annullati.

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;

-- Leggi i dati del conto.
SELECT balance FROM accounts WHERE account_id = 1;

-- Se un'altra transazione aggiorna il saldo, questi dati si aggiornano subito.
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

COMMIT;
  1. Repeatable Read

Questo livello garantisce che se leggi dei dati, resteranno invariati per te durante tutta la transazione.

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;

-- Leggi i dati del conto.
SELECT balance FROM accounts WHERE account_id = 1;

-- Anche se un'altra transazione aggiorna questo saldo, tu non vedrai il cambiamento.
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

COMMIT;
  1. Serializable

A questo livello la transazione lavora come se fosse l'unica nel sistema.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;

-- Leggi i dati del conto.
SELECT balance FROM accounts WHERE account_id = 1;

-- Qualsiasi altra transazione che prova a cambiare questi dati verrà bloccata finché la tua transazione non è finita.
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

COMMIT;

Come scegliere il livello di isolamento?

La scelta del livello di isolamento dipende dalle tue esigenze:

  • Se la velocità è più importante della precisione, e puoi sopportare le righe fantasma — scegli Read Committed.
  • Se la precisione conta, ma vuoi comunque performance alte — usa Repeatable Read.
  • Se ti serve il 100% di garanzia sulla correttezza dei dati, anche a costo di rallentare — ti serve Serializable.

Occhio! I livelli di isolamento più rigorosi possono portare a blocchi e cali di performance. La scelta giusta è sempre un compromesso tra performance e coerenza dei dati.

1
Sondaggio/quiz
Introduzione alle transazioni, livello 39, lezione 4
Non disponibile
Introduzione alle transazioni
Introduzione alle transazioni
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION