Condividi tramite


Livelli di isolamento delle transazioni (ODBC)

I livelli di isolamento delle transazioni sono una misura della portata in cui l'isolamento delle transazioni ha esito positivo. In particolare, i livelli di isolamento delle transazioni sono definiti dalla presenza o dall'assenza dei fenomeni seguenti:

  • Letture dirty Una lettura dirty si verifica quando una transazione legge dati di cui non è ancora stato eseguito il commit. Si supponga, ad esempio, che la transazione 1 aggiorni una riga. La transazione 2 legge la riga aggiornata prima che la transazione 1 esegua il commit dell'aggiornamento. Se la transazione 1 esegue il rollback della modifica, la transazione 2 avrà dati di lettura da considerarsi come mai esistiti.

  • Letture non ripetibili Una lettura non ripetibile si verifica quando una transazione legge la stessa riga due volte, ma ogni volta ottiene dati diversi. Si supponga, ad esempio, che la transazione 1 legga una riga. La transazione 2 aggiorna o elimina tale riga ed esegue il commit dell'aggiornamento o dell'eliminazione. Se la transazione 1 rilegge la riga, recupera valori di riga diversi o rileva che la riga è stata eliminata.

  • Fantasmi Un fantasma è una riga che corrisponde ai criteri di ricerca, ma inizialmente non viene vista. Si supponga, ad esempio, che la transazione 1 legga un set di righe che soddisfano alcuni criteri di ricerca. La transazione 2 genera una nuova riga (tramite un aggiornamento o un inserimento) che corrisponde ai criteri di ricerca per la transazione 1. Se la transazione 1 esegue nuovamente l'istruzione che legge le righe, ottiene un set di righe diverso.

I quattro livelli di isolamento delle transazioni (come definito da SQL-92) sono definiti in termini di questi fenomeni. Nella tabella seguente, la "X" contrassegna ogni fenomeno che può verificarsi.

Livello di isolamento della transazione Letture dirty Letture non ripetibili Fantasmi
Read Uncommitted X X X
Read Committed -- X X
Lettura ripetibile -- -- X
Serializable -- -- --

La tabella seguente descrive semplici modalità in cui un DBMS potrebbe implementare i livelli di isolamento delle transazioni.

Importante

La maggior parte dei DBMS usa schemi più complessi rispetto a questi per aumentare la concorrenza. Questi esempi vengono forniti solo a scopo illustrativo. In particolare, ODBC non stabilisce il modo in cui determinati DBMS isolano le transazioni l'una dall'altra.

Isolamento della transazione Implementazione possibile
Read Uncommitted Le transazioni non sono isolate l'una dall'altra. Se DBMS supporta altri livelli di isolamento delle transazioni, ignora qualsiasi meccanismo usato per implementare tali livelli. Affinché non influiscano negativamente su altre transazioni, le transazioni in esecuzione a livello di lettura senza commit sono in genere di sola lettura.
Read Committed La transazione attende fino a quando le righe bloccate da altre transazioni non vengono sbloccate; ciò impedisce la lettura di dati "dirty".

La transazione contiene un blocco di lettura (se legge solo la riga) o un blocco di scrittura (se aggiorna o elimina la riga) nella riga corrente per impedire ad altre transazioni di aggiornarla o eliminarla. La transazione rilascia blocchi di lettura quando si sposta dalla riga corrente. Mantiene blocchi di scrittura fino a quando non viene eseguito il commit o il rollback.
Lettura ripetibile La transazione attende fino a quando le righe bloccate da altre transazioni non vengono sbloccate; ciò impedisce la lettura di dati "dirty".

La transazione contiene blocchi di lettura su tutte le righe restituite all'applicazione e blocchi di scrittura su tutte le righe inserite, aggiornate o eliminate. Ad esempio, se la transazione include l'istruzione SQL SELECT * FROM Orders, la transazione blocca la lettura delle righe durante il recupero da parte dell'applicazione. Se la transazione include l'istruzione SQL DELETE FROM Orders WHERE Status = 'CLOSED', la transazione blocca la scrittura delle righe durante l'eliminazione.

Poiché altre transazioni non possono aggiornare o eliminare queste righe, la transazione corrente evita letture non ripetibili. La transazione rilascia il blocco solo dopo aver eseguito il commit o il rollback.
Serializable La transazione attende fino a quando le righe bloccate da altre transazioni non vengono sbloccate; ciò impedisce la lettura di dati "dirty".

La transazione contiene un blocco di lettura (se legge solo le righe) o un blocco di scrittura (se può aggiornare o eliminare righe) nell'intervallo di righe su cui influisce. Ad esempio, se la transazione include l'istruzione SQL SELECT * FROM Orders, l'intervallo è l'intera tabella Orders; la transazione blocca la lettura della tabella, non consentendo l'inserimento di nuove righe. Se la transazione include l'istruzione SQL DELETE FROM Orders WHERE Status = 'CLOSED', l'intervallo corrisponde a tutte le righe con stato "CLOSED"; la transazione blocca la scrittura di tutte le righe della tabella Orders con stato "CLOSED" e non consente l'inserimento o l'aggiornamento di righe in modo che la riga risultante abbia uno stato "CLOSED".

Poiché altre transazioni non possono aggiornare o eliminare le righe nell’intervallo, la transazione corrente evita letture non ripetibili. Poiché altre transazioni non possono inserire righe nell'intervallo, la transazione corrente evita eventuali righe fantasma. La transazione rilascia il blocco solo dopo aver eseguito il commit o il rollback.

È importante notare che il livello di isolamento delle transazioni non influisce sulla capacità di una transazione di visualizzare le proprie modifiche; le transazioni possono sempre visualizzare le modifiche apportate. Ad esempio, una transazione può essere costituita da due istruzioni UPDATE, la prima delle quali aumenta il salario di tutti i dipendenti del 10% e la seconda delle quali imposta il pagamento di tutti i dipendenti al di sopra di un importo massimo a tale importo. Questa operazione ha esito positivo solo come singola transazione perché la seconda istruzione UPDATE può visualizzare i risultati della prima.