Come dice brb tea, dipende dall'implementazione del database e dall'algoritmo che usano: MVCC o Two Phase Locking.
CUBRID (RDBMS open source) spiega l'idea di questi due algoritmi:
Il primo è quando la transazione T2 tenta di modificare il record A, sa che la transazione T1 ha già modificato il record A e attende fino al completamento della transazione T1 perché la transazione T2 non può sapere se la transazione T1 verrà confermata o rollata indietro. Questo metodo è chiamato bloccaggio a due fasi (2PL).
- Controllo della concorrenza multi-versione (MVCC)
L'altro è consentire a ciascuna di esse, transazioni T1 e T2, di avere le proprie versioni modificate. Anche quando la transazione T1 ha modificato il record A da 1 a 2, la transazione T1 lascia il valore originale 1 così com'è e scrive che la versione della transazione T1 del record A è 2. Quindi, la seguente transazione T2 cambia il record A da 1 a 3, non da 2 a 4, e scrive che la versione della transazione T2 del record A è 3.
Quando viene eseguito il rollback della transazione T1, non importa se il 2, la versione della transazione T1, non viene applicato al record A. Dopodiché, se viene eseguito il commit della transazione T2, la 3, la versione della transazione T2, verrà applicata al record A. Se viene eseguito il commit della transazione T1 prima della transazione T2, il record A viene modificato in 2 e quindi in 3 al momento del commit della transazione T2. Lo stato finale del database è identico allo stato di esecuzione di ciascuna transazione in modo indipendente, senza alcun impatto su altre transazioni. Pertanto, soddisfa la proprietà ACID. Questo metodo è denominato Multi-version concurrency control (MVCC).
L'MVCC consente modifiche simultanee al costo di un maggiore overhead in memoria (perché deve mantenere versioni diverse degli stessi dati) e di calcolo (nel livello REPETEABLE_READ non puoi perdere gli aggiornamenti quindi deve controllare le versioni dei dati, come Hiberate fa con Optimistick Locking ).
In 2PL i livelli di isolamento delle transazioni controllano quanto segue :
Indica se i blocchi vengono presi quando i dati vengono letti e che tipo di blocchi vengono richiesti.
Per quanto tempo vengono mantenuti i blocchi di lettura.
Se un'operazione di lettura che fa riferimento a righe modificate da un'altra transazione:
Blocca finché non viene liberato il blocco esclusivo sulla riga.
Recupera la versione confermata della riga che esisteva al momento in cui è iniziata l'istruzione o la transazione.
Leggere la modifica dei dati non salvata.
La scelta di un livello di isolamento della transazione non influisce sui blocchi acquisiti per proteggere le modifiche ai dati. Una transazione ottiene sempre un blocco esclusivo su tutti i dati che modifica e mantiene tale blocco fino al completamento della transazione, indipendentemente dal livello di isolamento impostato per quella transazione. Per le operazioni di lettura, i livelli di isolamento delle transazioni definiscono principalmente il livello di protezione dagli effetti delle modifiche apportate da altre transazioni.
Un livello di isolamento inferiore aumenta la capacità di molti utenti di accedere ai dati contemporaneamente, ma aumenta il numero di effetti di concorrenza , come letture sporche o aggiornamenti persi, che gli utenti potrebbero incontrare.
Esempi concreti della relazione tra blocchi e livelli di isolamento in SQL Server (utilizzare 2PL tranne su READ_COMMITED con READ_COMMITTED_SNAPSHOT = ON)
READ_UNCOMMITED: non emette blocchi condivisi per impedire ad altre transazioni di modificare i dati letti dalla transazione corrente. Le transazioni READ UNCOMMITTED non sono inoltre bloccate da blocchi esclusivi che impedirebbero alla transazione corrente di leggere le righe che sono state modificate ma non sottoposte a commit da altre transazioni. [...]
READ_COMMITED:
- Se READ_COMMITTED_SNAPSHOT è impostato su OFF (impostazione predefinita): utilizza blocchi condivisi per impedire ad altre transazioni di modificare le righe mentre la transazione corrente esegue un'operazione di lettura. I blocchi condivisi impediscono inoltre all'istruzione di leggere le righe modificate da altre transazioni fino al completamento dell'altra transazione. [...] I blocchi di riga vengono rilasciati prima che venga elaborata la riga successiva. [...]
- Se READ_COMMITTED_SNAPSHOT è impostato su ON, il Motore di database utilizza il controllo delle versioni delle righe per presentare a ciascuna istruzione un'istantanea coerente a livello di transazione dei dati così come erano all'inizio dell'istruzione. I blocchi non vengono utilizzati per proteggere i dati dagli aggiornamenti di altre transazioni.
REPETEABLE_READ: i blocchi condivisi vengono inseriti su tutti i dati letti da ciascuna istruzione nella transazione e vengono mantenuti fino al completamento della transazione.
SERIALIZZABILE: i blocchi dell'intervallo vengono inseriti nell'intervallo di valori chiave che corrispondono alle condizioni di ricerca di ciascuna istruzione eseguita in una transazione. [...] I blocchi dell'intervallo vengono mantenuti fino al completamento della transazione.