Vantaggi del SET LIVELLO DI ISOLAMENTO PER LE TRANSAZIONI LEGGUTO NON CONSIGLIATO


12

Uso SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDla maggior parte delle mie query SQL generali, principalmente perché questo mi è stato approfondito durante l'apprendimento della lingua.

Secondo la mia comprensione, questo livello di isolamento agisce nello stesso modo che WITH (NO LOCK)comunque io tendo sempre a usare SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

  • C'è sempre un momento che dovrei usare WITH (NO LOCK)sopra SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
  • Impedisce ad SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDaltri utenti di essere bloccato fuori dalle tabelle che sto leggendo?
  • Se SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDviene utilizzato per arrestare i blocchi, ma sto solo leggendo i dati, a che serve usarli? Sono solo le query a uso intensivo del sistema a generare blocchi? Vale la pena usarlo quando si eseguono query che tornerebbero ad esempio in 5-10 secondi?
  • Mi è stato detto di non utilizzare SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDdurante la lettura di dati che sarebbero stati utilizzati negli aggiornamenti, presumibilmente per evitare l'aggiornamento di dati sporchi. Questa sarebbe l'unica ragione?
  • Con il tipo di database su cui sto lavorando, esiste un ambiente di produzione e test. Molto raramente eseguiremo query sull'ambiente di produzione, ma quando ne avrò bisogno, utilizzerò generalmente la SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDmia query. Capisco che letture sporche sono possibili con questo. A parte la ricezione di dati che potrebbero non finire per essere impegnati nel database (e quindi scartare i miei risultati) quali altri tipi di "letture sporche" potrebbero essere possibili?

Ci scusiamo per le domande di massa.


2
Potresti leggere gli stessi dati due volte è un'altra caduta. L'uso di RU o NO LOCK come standard è una cattiva idea.
James Anderson,

9
Non usereiREAD UNCOMMITTED ovunque, esattamente come non usereiWITH (NOLOCK) ovunque (sono essenzialmente la stessa cosa) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
Mark Sinkinson del

1
Guarda i modelli di isolamento SNAPSHOT. Sono molto più potenti di RCU e non bloccano né causano il blocco. Sembrano un buon modello predefinito per te (invece di default su RCU!).
usr

Risposte:


25

È terribile che tu l'abbia imparato in quel modo (scusa!).

READ UNCOMMITTEDleggiamo ogni riga, sì. Anche coloro che sono attualmente utilizzati in una INSERT, UPDATE, DELETEoperazione. Questo è molto utile se hai bisogno di dare una rapida occhiata ad alcuni Dati o in missioni critiche - SELECTDichiarazioni in cui un blocco sarebbe molto dannoso.

In effetti, rischi la tua integrità. È possibile che tu legga una riga, che al momento viene utilizzata per essere eliminata o modificata. Può anche sembrare che tu abbia letto un valore sbagliato. Questo può essere davvero insolito, ma può succedere. Cosa intendo con quello? Bene, pensa a una riga che è molto ampia (ha molte colonne con molte colonne lunghe nvarchar). Si verifica un aggiornamento su questa riga e imposta nuovi valori. In rari casi ti può capitare di leggere solo mezza riga. Un'altra cosa può succedere, ad esempio, se un utente modifica i suoi valori di accesso. Cambia la sua mail + password. La posta è già impostata, ma la password no. In questo modo hai uno stato incoerente.

Vorrei suggerire di dimenticare READ UNCOMMITTED. Usalo dove è veramente necessario.

Un'altra alternativa per te può essere quella di abilitare l' READ_COMMITTED_SNAPSHOTopzione del database, per cui puoi usarla a READ COMMITTED SNAPSHOTcausa del versioning di riga abilitato nel tuo tempdb. In questo modo hai appena letto un'altra versione (precedente) di una riga. Questo non bloccherà le tue query. Ma può capitare di leggere anche un vecchio valore, ma un valore vecchio coerente.

Un'altra idea può essere WITH(READPAST)invece di WITH(NOLOCK). Leggerai il vecchio stato della tabella (un po 'come nel SNAPSHOT ISOLATION), ma salterai invece tutte le righe attualmente bloccate.


@Ionico, grazie mille per la risposta! Apprezzo molto l'aiuto su questo.
dmoney,

@HingeSight, sembra proprio così, ma ci sono ottime possibilità che sia stata la mia interpretazione dell'affermazione, grazie in entrambi i modi per il tuo contributo.
dmoney,

1
SNAPSHOT ISOLATIONnon deve essere abilitato per poter essere acceso READ COMMITTED SNAPSHOT. È READ COMMITTED SNAPSHOTnecessario abilitare solo l' opzione del database in modo che il controllo delle versioni delle righe anziché il blocco per coerenza di lettura, evitando la necessità di letture sporche.
Dan Guzman,

Sì, intendevo dire @DanGuzman. Mi dispiace che la risposta non sia chiara in quel punto. L'ho modificato. :-)
Ionico

Con READPAST salterai i record bloccati, non otterrai i vecchi valori, quindi l'unico posto in cui ho capito che poteva essere usato è la gestione delle code
James Z

2

Come indicato nella risposta accettata, dimentica di utilizzare il livello di isolamento READ UNCOMMITTED (tranne quando realmente necessario) poiché rischi di leggere dati errati. Ma per rispondere al terzo punto elenco nella tua domanda ci sono due situazioni che trovo utili:

  1. Durante la scrittura e il test di pacchetti SSIS di SQL Server, i passaggi del pacchetto possono essere inseriti in una transazione. Se si sta testando un pacchetto eseguendolo passo dopo passo nel debugger SSIS, è possibile esaminare le tabelle mentre sono presenti blocchi sulla tabella. L'utilizzo di SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED consente di utilizzare SQL Server Manager Studio per esaminare le tabelle durante il debug del pacchetto.

  2. In SQL Server Manager Studio potresti voler testare il codice T-SQL avvolgendolo in una transazione per darti la possibilità di ripristinare le modifiche. Ad esempio, su un database di test è possibile ripristinare i dati allo stato iniziale come parte del test. Se si sta eseguendo il test del codice con wrapping della transazione e si desidera controllare le tabelle bloccate mentre la transazione è in corso, è possibile utilizzare SET LEVEL ISOLATION TRANSATION READ UNCOMMITTED per esaminare i valori in un'altra finestra.

Accetto che questi siano usi piuttosto oscuri per READ UNCOMMITTED, ma li ho trovati utili in un ambiente di test.


1

Nella maggior parte dei database, la stragrande maggioranza delle attività, anche inserimenti, eliminazioni e aggiornamenti, sono al di fuori delle transazioni esplicite.

Certo, READ UNCOMMITTED(Letture sporche) può fornire informazioni errate in questi casi, ma queste informazioni erano corrette 5 secondi prima.

I tempi in cui Dirty Reads producono risultati veramente negativi sono quando una Transazione fallisce e deve essere ripristinata o quando si esegue una query su due tabelle che vengono normalmente aggiornate insieme usando una transazione esplicita.

Nel frattempo, su un tipico database di grandi dimensioni, occupato che ha un rapporto 100 (o più) a 1 tra letture e scritture, OGNI singola query (di lettura) che non utilizza Dirty Reads rallenta il sistema perché deve ottenere e controllare per i blocchi E sta rendendo molto più probabile che le transazioni falliscano (in genere a causa di deadlock) che possono causare problemi di integrità del database più gravi.

Invece, l'uso di letture sporche rende il sistema MOLTO più veloce e più affidabile (in parte a causa del miglioramento delle prestazioni che rende meno probabili le incoerenze).

Certo, ci sono momenti in cui non dovrebbero essere usati. Non mi piace impostare il database per impostazione predefinita sull'uso del READ UNCOMMITTEDlivello di isolamento o persino sull'uso dell'istruzione esplicita SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDall'inizio di SQL Script e SP - ci sono troppe possibilità che accada una lettura sporca quando non dovrebbe. Invece, i (NOLOCK)suggerimenti sono un approccio molto migliore poiché indicano esplicitamente che il programmatore ha pensato a quello che stavano facendo e ha deciso che, per questa tabella specifica in questa specifica query, Dirty Reads era sicuro.

Se stai programmando un'applicazione per trasferire denaro da un conto bancario a un altro, non dovresti utilizzare Dirty Reads. Ma la maggior parte delle applicazioni non necessita di quel livello di paranoia.

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.