ALLOW_SNAPSHOT_ISOLATION e READ_COMMITTED_SNAPSHOT


38

La maggior parte del forum e dell'esempio online suggeriscono sempre di avere entrambi ALLOW_SNAPSHOT_ISOLATIONe READ_COMMITTED_SNAPSHOTimpostare su ON ogni volta che qualcuno sta chiedendo un'istantanea, il controllo delle versioni delle righe o una domanda simile.

Immagino che la parola SNAPSHOT in entrambe le impostazioni diventi un po 'confusa. Ho pensato che, in modo che il motore di database da utilizzare versioni delle righe invece di serrature per comportamento predefinito READ_COMMITTED, il database READ_COMMITTED_SNAPSHOTè impostata su ON , indipendentemente di ciò che ALLOW_SNAPSHOT_ISOLATIONl'impostazione.

L' ALLOW_SNAPSHOT_ISOLATIONimpostazione è impostata su ON solo per consentire l'isolamento snapshot quando si avvia una transazione (ad esempio SET TRANSACTION ISOLATION LEVEL SNAPSHOT) a prescindere di READ_COMMITTED_SNAPSHOTimpostazione.

L'unico motivo per impostare queste due impostazioni su ON è quando è necessario avere il READ COMMITTED versioning delle righe E l' isolamento dello snapshot.

La mia domanda è: la mia comprensione è errata in qualche modo? E che queste due impostazioni devono essere sempre impostate su ON insieme (specialmente per il READ COMMITTED row versioning)?

Risposte:


25

La tua comprensione è corretta. Diventa un po 'confuso.

Kim Tripp (uno dei programmatori di SQL Server e parte integrante di SQLSkills) analizza esattamente ciò che hai affermato nei video MCM su Snapshot Isolation . Fwd veloce a 41:45 nel video per arrivare alla parte in cui risponde alla tua domanda.

Se lo utilizzi, ALLOW_SNAPSHOT_ISOLATIONassicurati di utilizzare SET TRANSACTION ISOLATION LEVEL SNAPSHOTnel tuo codice, altrimenti non otterrai alcun vantaggio.

Se si imposta SET READ_COMMITTED_SNAPSHOT ON, non è necessario modificare alcun codice. MS SQL Server applica automaticamente l'isolamento dello snapshot per quella tabella.

Non ho testato per vedere cosa succede se chiedi un diverso livello di isolamento nel tuo codice, sospetto che sovrascriverà questa opzione ma prima lo testerò.

Una rapida occhiata alle prestazioni generali usando Isolamento istantanea.

Un buon articolo su come l'isolamento dello snapshot può cambiare il comportamento previsto della tua app . Mostra esempi di come un'istruzione di aggiornamento e un'istruzione select potrebbero restituire risultati totalmente diversi e inaspettati.


Grazie per il link Come altri BOL, ha discusso di queste due impostazioni in modo indipendente e collettivo (è lì che diventa un po 'confuso, o forse ci penso troppo). Ho dovuto provarlo per capire meglio.
Travis,

4
Questa è un'ottima risposta e vorrei solo chiarire un paio di voci. Innanzitutto, se stai solo eseguendo la scansione del video, inizia alle 23:18 e alle 41:45. La prima volta aggiunge più dettagli. Sebbene Kim menzioni una risposta alla domanda originale, è comunque necessario modificare il codice se si utilizzano entrambi. Read_Committed_Snapshot è l'isolamento a livello di istruzione, in altre parole si applica solo all'istruzione attualmente in esecuzione. Allow_Snapshot_Isolation è l'isolamento a livello di transazione, tutto compreso tra Begin Tran e Commit. Possono essere impegnati separatamente, ma viene stabilito lo stesso overhead di 14 byte per riga.
Delux,

grazie per aver aggiunto i dettagli aggiuntivi sull'overhead di 14 byte che si sta stabilendo. Kim lo attraversa nel video, ma è molto utile averlo anche qui nel testo.
Ali Razeghi,

15

OK, sono tornato a casa e testato. Ecco l'osservazione.

CREATE DATABASE TEST;
GO
CREATE TABLE TABLE1
(
    ID tinyint,
    Details varchar(10)
);
GO
INSERT INTO TABLE1
VALUES (1, 'Original');
GO

SELECT
    name,
    snapshot_isolation_state_desc,
    is_read_committed_snapshot_on
FROM sys.databases
WHERE name = 'TEST';
GO

Primo test con entrambe le impostazioni confermate su OFF.

Query 1

USE TEST;

BEGIN TRAN
UPDATE TABLE1
SET Details = 'Update'
WHERE ID = 1;

--COMMIT;
--ROLLBACK;
GO

Query 2

USE TEST;

SELECT ID, Details
FROM TABLE1
WHERE ID = 1;
GO

In questo test, la query 2 è in attesa del commit della query 1, dm_tran_locks DMV mostra quel blocco esclusivo sulla TABELLA 1 sostenuto dalla query 1.

USE TEST;

SELECT
    DB_NAME(tl.resource_database_id) AS DBName,
    resource_type,
    OBJECT_NAME(resource_associated_entity_id) AS tbl_name,
    request_mode,
    request_status,
    request_session_id
FROM sys.dm_tran_locks tl
WHERE 
    resource_database_id = db_id('TEST')
    AND resource_type = 'OBJECT'

Secondo test , ripristinare la transazione precedente, impostare READ_COMMITTED_SNAPSHOT ON ma lasciare ALLOW_SNAPSHOT_ISOLATION OFF.

ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT ON
WITH ROLLBACK IMMEDIATE;
GO

Eseguire la query 1 ed eseguire la query 2. DMV mostra che la query 1 comporta un blocco esclusivo, ma la query 2 restituisce i dettagli con "Originale" senza che la query 1 esegua il commit della transazione. Sembra che READ_COMMITTED versioning delle righe sia attivo.

L'aggiunta SET TRANSACTION ISOLATION LEVEL SNAPSHOT;alla query 1 e alla query 2 e l'esecuzione della query 1 o della query 2 restituiscono un errore: la transazione di isolamento dello snapshot non è riuscita ad accedere al database 'TEST' perché l'isolamento dello snapshot non è consentito in questo database. Utilizzare ALTER DATABASE per consentire l'isolamento dello snapshot.

Terzo test , rollback della transazione precedente. Impostare READ_COMMITTED_SNAPSHOT OFF e ALLOW_SNAPSHOT_ISOLATION ON.

ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT OFF
WITH ROLLBACK IMMEDIATE;
GO

ALTER DATABASE TEST
SET ALLOW_SNAPSHOT_ISOLATION ON;
GO

Eseguire la query 1, quindi la query 2. DMV mostra il blocco esclusivo sostenuto dalla query 1. La query 2 sembra essere in attesa del completamento della query 1. L'attivazione di ALLOW_SNAPSHOT_ISOLATION su ON non sembra abilitare il READ COMMITTED versioning delle righe.

Aggiunta SET TRANSACTION ISOLATION LEVEL SNAPSHOT;sia alla query 1 che alla query 2. Eseguire la query 1 e quindi la query 2. Mentre DMV mostra che la query 1 comporta un blocco esclusivo, la query 2 restituisce i dettagli con "Originale". L'isolamento dello snapshot sembra essere in atto.

L'osservazione del test mostra che READ_COMMITTED_SNAPSHOTessa stessa abilita / disabilita il READ COMMITTED versioning delle file indipendentemente ALLOW_SNAPSHOT_ISOLATIONdall'impostazione e viceversa.


4

La tua comprensione è corretta. Mi piace la definizione breve, pulita e semplice da qui :

Quando l'opzione del database READ_COMMITTED_SNAPSHOT è ATTIVATA, le transazioni che impostano il livello di isolamento di commit della lettura utilizzano il controllo delle versioni delle righe.

Quando l'opzione del database ALLOW_SNAPSHOT_ISOLATION è ON, le transazioni possono impostare il livello di isolamento dello snapshot.

Sembra che molti malintesi provengano dalla stessa SM. Ad esempio, qui dicono:

Se si imposta l'opzione di database READ_COMMITTED_SNAPSHOT su ON, il motore di database utilizza il controllo delle versioni delle righe e l'isolamento dello snapshot come predefinito, anziché utilizzare i blocchi per proteggere i dati.

Ma il suddetto "isolamento dello snapshot" non è uguale al comportamento della transazione per cui set transaction isolation level snapshotviene applicato.

Per quanto riguarda la differenza, una bella spiegazione è qui .

Probabilmente sarebbe meglio se READ_COMMITTED_SNAPSHOT fosse nominato READ_COMMITTED_ROW_VERSIONING o qualcosa del genere. :)


0

Mi piace questo riepilogo di Microsoft :

L'impostazione dell'opzione READ_COMMITTED_SNAPSHOT ON consente l'accesso alle righe con versione nel livello di isolamento READ COMMITTED predefinito. Se l'opzione READ_COMMITTED_SNAPSHOT è impostata su OFF, è necessario impostare esplicitamente il livello di isolamento dello snapshot per ogni sessione per accedere alle righe con versione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.