Situazione migliore per utilizzare il livello di isolamento READ UNOMOMITTED


10

Come tutti sappiamo, READ UNCOMMITTED è il livello di isolamento più basso in cui possono accumularsi cose come letture sporche e letture fantasma. Qual è il momento migliore per utilizzare questo livello di isolamento e per quali motivi potrebbe essere utilizzato?

In realtà ho letto le risposte prima, ma non sono riuscito a capirlo completamente perché non c'erano abbastanza esempi.

Risposte:


20

Uso READ_UNCOMMITTED(o NOLOCK) quando eseguo query su database di produzione da SSMS ma non di routine dal codice dell'applicazione. Questa pratica (insieme a un suggerimento per le query MAXDOP 1) aiuta a garantire che le query casuali per l'analisi dei dati e la risoluzione dei problemi non influiscano sul carico di lavoro di produzione, con la consapevolezza che i risultati potrebbero non essere corretti.

Purtroppo, vedo READ_UNCOMMITTED/ NOLOCKutilizzo ampiamente nel codice di produzione per evitare il blocco a spese dell'integrità dei dati. La soluzione corretta è un livello di isolamento per il controllo delle versioni di riga ( SNAPSHOTo READ_COMMITTEDcon l' READ_COMMITTED_SNAPSHOTopzione del database ON) e / o attenzione all'ottimizzazione di query e indice.

Di recente ho rivisto il codice di un proc in cui l'unica modifica era rimuovere NOLOCKperché a volte restituiva risultati errati. La rimozione è NOLOCKstata una buona cosa ma, sapendo che le righe mancate o duplicate si verificano in genere durante le scansioni dell'ordine di allocazione di tabelle di grandi dimensioni, ho suggerito anche il refactoring di utilizzare una UNION ALLtecnica per promuovere un uso efficiente dell'indice. La query ora viene eseguita in pochi millisecondi con risultati corretti, il migliore di tutti i mondi.


7

Penso che vada bene in alcune circostanze, purché tu accetti le conseguenze e non abbia altre opzioni.

Per altre opzioni, spingerei le persone verso l'uso dell'isolamento di lettura istantanea (RCSI) per nuove applicazioni o SNAPSHOT ISOLATION (SI) per le applicazioni precedenti, dove non è possibile testare facilmente l'intera base di codice per le condizioni di gara con RCSI.

Tuttavia, quelli potrebbero non essere adatti. Potrebbe essere necessario dedicare un po 'di tempo extra ad amare e prendersi cura di tempdb e assicurarsi che nessuno lasci una transazione aperta che fa crescere l'archivio versione (e tempdb) e riempie il disco.

Se non si dispone di un DBA o di qualcuno il cui compito è monitorare e gestire il proprio SQL Server, tali opzioni possono essere pericolose. Più in generale, non tutti hanno il pieno controllo del codice che va al proprio server dove possono cambiare la stringa di connessione o il codice per richiedere SI per domande sul problema.

Oltre a ciò, la maggior parte delle persone non ha problemi di blocco con l' intera applicazione . Hanno problemi con cose come la segnalazione di dati OLTP. Se puoi accettare i compromessi di NOLOCK / RU in cambio di quei rapporti che non sono stati bloccati dagli scrittori, prova.

Assicurati solo di capire cosa significhi. Non significa che la tua query non accetta alcun blocco, significa che non rispetta i blocchi estratti da altre query.

E, naturalmente, se il tuo problema è il blocco scrittore / scrittore, l'unica opzione che ti aiuterà è SI, ma ci vorrebbe una quantità incredibile di lavoro degli sviluppatori per implementarlo correttamente con la gestione degli errori, ecc.


5
E se il problema riguarda davvero solo i dati OLTP, scaricarli su un secondario di sola lettura di qualche tipo (AG, invio log, replica o roll-your-own).
Aaron Bertrand

3
@AaronBertrand E poi avrebbero un secondo server da monitorare;)
Erik Darling,

5

IMHO l' unico caso d'uso valido per READ UNCOMMITTED su un sistema moderno è quando si esegue il debug di una sessione da un'altra in fase di sviluppo, in modo da poter vedere cosa sta facendo mentre, ad esempio, un proc memorizzato è ancora in esecuzione. Normalmente non verrebbe mai utilizzato in un sistema di produzione. Potrebbero esserci alcuni guadagni di prestazione minori ma a lungo termine non ne varrà mai la pena.


3

Lo usiamo sempre in ambito sanitario.

È sorprendentemente raro che singole righe di dati cambino a metà query e il rapporto di lettura / scrittura è come 10.000 / 1 - e la maggior parte di questi sono inserti, non aggiornamenti. Ad esempio, quando l'interfaccia di laboratorio scrive i risultati di laboratorio di un paziente nel database, tali valori non cambieranno mai.

Quando i dati non cambia, cambia una riga alla volta. Nessuno sta aggiornando intere colonne (tranne un DBA, quando sbagliano davvero).

Dall'altro lato, eseguiamo un sacco di domande per cercare cose come pazienti che ritornano al pronto soccorso in 72 ore o meno, il che martella assolutamente i tavoli.

In 10 anni di assistenza sanitaria SQL, non ho mai visto a Rollback Transaction. Voglio entrare e uscire senza interrompere l'esperienza dell'utente finale. Se c'è un alto rischio di rallentamento del database OLTP e un basso rischio di ottenere dati errati, NOLOCK.

Dovremmo usarlo? Forse sì forse no. In generale, non direi che molti dei database delle applicazioni su cui ho lavorato sono ben progettati. Normalmente sono pieni di anti-pattern.


4
solo FYI, è possibile leggere le righe parzialmente scritte con nolock.
Max Vernon,

1
Oof! Ho davvero bisogno di convincere il mio capo a comprarmi un altro server in modo da poter accedere a questa roba ....
James,

3
Potresti essere interessato a questo elegante post sul blog di Paul White su LEGGI UNCOMMITTED, in particolare la sezione "Lettura dei dati corrotti": Il livello di isolamento letto senza impegno
Josh Darnell,

1

READ_UNCOMMITTED/NOLOCKè una buona opzione quando l'accuratezza dei dati non è in realtà l'obiettivo principale. A volte quando è necessario un conteggio aggregato approssimativo. Ad esempio: esistono stored procedure utilizzate per le tabelle INSERT o UPDATE. A volte il numero di record da aggiornare o inserire è enorme (Migliaia di record). Durante queste esecuzioni di procedure memorizzate, possiamo eseguire NOLOCKperiodicamente una semplice query di selezione con sulla tabella di destinazione per vedere se procede senza intoppi (per la query di aggiornamento, se si dispone di una colonna di modifica dello stato per i record da aggiornare, è possibile utilizzare quella colonna per eseguire la group byquery con NOLOCKper sapere se il conteggio dei cambiamenti di stato è in costante cambiamento).


0

Ricorda che LEGGI UNCOMMITTED introduce ulteriori problemi di coerenza, non solo letture sporche. A seconda del metodo di accesso, potresti perdere righe o persino leggere la stessa riga più di una volta. Se sei interessato ai dettagli, leggi l'articolo di Itzik Ben-Gan


3
Righe mancanti e leggere righe più di una volta è possibile anche a livello di commit lettura predefinito. Se una colonna chiave indice viene aggiornata durante la scansione e si sposta.
Martin Smith,

La discussione laterale su questa risposta è stata spostata nella chat .
Paul White 9
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.