Utilizzo di livelli di isolamento basati sul controllo delle versioni delle righe
In MicrosoftSQL Server l'infrastruttura di controllo delle versioni delle righe è sempre attivata e viene utilizzata da più funzionalità. Oltre a offrire livelli di isolamento basati sul controllo delle versioni delle righe, viene utilizzata per supportare le modifiche apportate in trigger e sessioni MARS (Multiple Active Result Sets) e le letture di dati per le operazioni sugli indici in linea.
I livelli di isolamento basati sul controllo delle versioni delle righe sono attivati a livello di database. Le applicazioni che accedono agli oggetti da database abilitati possono eseguire query utilizzando i livelli di isolamento seguenti:
Read Committed, che utilizza il controllo delle versioni delle righe impostando l'opzione di database READ_COMMITTED_SNAPSHOT su ON, come illustrato nell'esempio di codice seguente:
ALTER DATABASE AdventureWorks SET READ_COMMITTED_SNAPSHOT ON;
Quando il database è abilitato per READ_COMMITTED_SNAPSHOT, tutte le query in esecuzione nel livello di isolamento Read Committed utilizzano il controllo delle versioni delle righe, che significa che le operazioni di lettura non comportano il blocco di quelle di aggiornamento.
Isolamento dello snapshot, impostando l'opzione di database ALLOW_SNAPSHOT_ISOLATION su ON, come illustrato nell'esempio di codice seguente:
ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION ON;
Una transazione in esecuzione in un livello di isolamento dello snapshot può accedere alle tabelle nel database abilitate per lo snapshot. Per consentire l'accesso alle tabelle non abilitate per lo snapshot, è necessario modificare il livello di isolamento. Nell'esempio di codice seguente viene ad esempio illustrata un'istruzione SELECT che unisce in join due tabelle mentre è in esecuzione in una transazione snapshot. Una tabella appartiene a un database in cui non è stato attivato l'isolamento dello snapshot. Quando l'istruzione SELECT viene eseguita nel livello di isolamento dello snapshot, l'esecuzione non avviene correttamente.
SET TRANSACTION ISOLATION LEVEL SNAPSHOT; BEGIN TRAN SELECT t1.col5, t2.col5 FROM Table1 as t1 INNER JOIN SecondDB.dbo.Table2 as t2 ON t1.col1 = t2.col2;
Nell'esempio di codice seguente viene illustrata la stessa istruzione SELECT modificata in modo che il livello di isolamento della transazione sia Read Committed. Grazie a questa modifica, l'istruzione SELECT viene eseguita correttamente.
SET TRANSACTION ISOLATION LEVEL SNAPSHOT; BEGIN TRAN SELECT t1.col5, t2.col5 FROM Table1 as t1 WITH (READCOMMITTED) INNER JOIN SecondDB.dbo.Table2 as t2 ON t1.col1 = t2.col2;
Per ulteriori informazioni sull'impostazione del livello di isolamento in un'applicazione, vedere Modifica dei livelli di isolamento delle transazioni.
Limiti per le transazioni che utilizzano livelli di isolamento basati sul controllo delle versioni delle righe
Quando si utilizzano livelli di isolamento basati sul controllo delle versioni delle righe, considerare i limiti seguenti:
Non è possibile attivare READ_COMMITTED_SNAPSHOT in tempdb, msdb o master.
Le tabelle temporanee globali sono archiviate in tempdb. Quando si accede a una tabella temporanea globale all'interno di una transazione snapshot, è necessario che si verifichi una delle condizioni seguenti:
Impostare su ON l'opzione di database ALLOW_SNAPSHOT_ISOLATION in tempdb.
Utilizzare un hint di isolamento per modificare il livello di isolamento per l'istruzione.
Le transazioni snapshot non hanno esito positivo nei casi seguenti:
Quando un database viene impostato come di sola lettura dopo l'avvio della transazione snapshot, ma prima dell'accesso al database da parte della transazione stessa.
Se si accede agli oggetti da più database, quando lo stato di un database è stato modificato in modo che il recupero del database sia avvenuto dopo l'avvio di una transazione snapshot, ma prima dell'accesso al database da parte della transazione stessa. Quando, ad esempio, il database è stato impostato su OFFLINE e quindi su ONLINE, si è chiuso automaticamente e quindi si è aperto oppure è stato scollegato e quindi collegato.
Le transazioni distribuite, incluse le query in database partizionati distribuiti, non sono supportate nel livello di isolamento dello snapshot.
Tramite SQL Server non vengono mantenute più versioni dei metadati di sistema. Le istruzioni DLL (Data Definition Language) in tabelle e altri oggetti di database, ad esempio indici, viste, tipi di dati, stored procedure e funzioni CLR, comportano la modifica dei metadati. Se un oggetto viene modificato da un'istruzione DLL, eventuali riferimenti simultanei all'oggetto nel livello di isolamento dello snapshot causano un errore della transazione. Le transazioni Read Committed non hanno questo limite quando l'opzione di database READ_COMMITTED_SNAPSHOT è impostata su ON.
Un amministratore del database esegue, ad esempio, l'istruzione ALTER INDEX seguente.
USE AdventureWorks; GO ALTER INDEX AK_Employee_LoginID ON HumanResources.Employee REBUILD; GO
Le transazioni snapshot attive al momento dell'esecuzione di ALTER INDEX ricevono un errore nel caso in cui cerchino di fare riferimento alla tabella HumanResources.Employee successivamente all'esecuzione dell'istruzione ALTER INDEX. Le transazioni Read Committed che utilizzano il controllo delle versioni delle righe non sono interessate.
[!NOTA]
Le operazioni di tipo BULK INSERT possono comportare modifiche ai metadati della tabella di destinazione, ad esempio quando si disattiva la verifica dei vincoli. In questo caso, le transazioni di isolamento dello snapshot simultanee che accedono a tabelle in cui è stato eseguito l'inserimento bulk non hanno esito positivo.
Vedere anche