Risposte:
Questo livello di isolamento consente letture sporche. Una transazione può vedere le modifiche non confermate apportate da un'altra transazione.
Per mantenere il massimo livello di isolamento, un DBMS di solito acquisisce blocchi sui dati, il che può comportare una perdita di concorrenza e un elevato sovraccarico di blocco. Questo livello di isolamento rilassa questa proprietà.
Potresti voler leggere l' articolo di WikipediaREAD UNCOMMITTED
per alcuni esempi e ulteriori letture.
Potresti anche essere interessato a leggere l' articolo del blog di Jeff Atwood su come lui e il suo team hanno affrontato un problema di deadlock nei primi giorni di Stack Overflow. Secondo Jeff:
Ma è
nolock
pericoloso? Potresti finire con la lettura di dati non validi conread uncommitted
on? Sì, in teoria. Non mancheranno gli astronauti dell'architettura del database che iniziano a far cadere la scienza ACID su di te e tutti ma tirano l'allarme antincendio dell'edificio quando dici loro che vuoi provarenolock
. È vero: la teoria fa paura. Ma ecco cosa penso: "In teoria non c'è differenza tra teoria e pratica. In pratica c'è".Non consiglierei mai di utilizzare
nolock
come soluzione generale "buono per ciò che ti affligge" l'olio di serpente per eventuali problemi di deadlock del database che potresti avere. Dovresti prima provare a diagnosticare l'origine del problema.Ma in pratica l'aggiunta
nolock
a domande che conosci assolutamente sono affari di sola lettura semplici che non sembrano mai portare a problemi ... Finché sai cosa stai facendo.
Un'alternativa al READ UNCOMMITTED
livello che potresti voler prendere in considerazione è la READ COMMITTED SNAPSHOT
. Citando di nuovo Jeff:
Le istantanee si basano su un metodo di tracciamento delle modifiche dei dati completamente nuovo ... più che una leggera modifica logica, richiede al server di gestire i dati fisicamente in modo diverso. Una volta abilitato questo nuovo metodo di tracciamento della modifica dei dati, crea una copia o un'istantanea di ogni modifica dei dati. Leggendo queste istantanee anziché i dati in tempo reale durante i conflitti, i blocchi condivisi non sono più necessari nelle letture e le prestazioni complessive del database potrebbero aumentare.
READ UNCOMMITTED
può anche farti leggere le righe due volte o perdere intere righe . Se durante la lettura si verifica una divisione della pagina, puoi perdere interi blocchi di dati. WITH(NOLOCK)
dovrebbe essere usato solo se la precisione dei risultati non è importante
Questo può essere utile per vedere lo stato di avanzamento delle query di inserimento lungo, fare stime approssimative (simili COUNT(*)
o approssimative SUM(*)
) ecc.
In altre parole, i risultati restituiti dalle query di lettura sporche vanno bene purché le trattiate come stime e non prendiate decisioni critiche basate su di esse.
Il mio caso d'uso preferito read uncommited
è il debug di qualcosa che sta accadendo all'interno di una transazione.
Avviare il software con un debugger, mentre si passa attraverso le righe di codice, apre una transazione e modifica il database. Mentre il codice viene arrestato, è possibile aprire un analizzatore di query, impostare il livello di isolamento non letto letto ed eseguire query per vedere cosa sta succedendo.
È inoltre possibile utilizzarlo per verificare se le procedure di esecuzione prolungata sono bloccate o aggiornare correttamente il database.
È fantastico se la tua azienda ama creare procedure memorizzate eccessivamente complesse.
Il vantaggio è che può essere più veloce in alcune situazioni. Lo svantaggio è che il risultato può essere errato (i dati non ancora commessi potrebbero essere restituiti) e non vi è alcuna garanzia che il risultato sia ripetibile.
Se ti interessa la precisione, non usare questo.
Ulteriori informazioni sono su MSDN :
Implementa la lettura sporca o il blocco del livello di isolamento 0, il che significa che non vengono emessi blocchi condivisi e non vengono rispettati blocchi esclusivi. Quando questa opzione è impostata, è possibile leggere dati non impegnati o sporchi; i valori nei dati possono essere modificati e le righe possono apparire o scomparire nel set di dati prima della fine della transazione. Questa opzione ha lo stesso effetto dell'impostazione di NOLOCK su tutte le tabelle in tutte le istruzioni SELECT in una transazione. Questo è il meno restrittivo dei quattro livelli di isolamento.
select
istruzioni non dovrebbero attendere per acquisire blocchi condivisi su risorse bloccate esclusivamente da altre transazioni.
Quando va bene usare READ UNCOMMITTED
?
Buono : report aggregati di grandi dimensioni che mostrano totali in costante evoluzione.
Rischi : quasi tutto il resto.
La buona notizia è che la maggior parte dei rapporti di sola lettura rientrano in quella buona categoria.
Ok per usarlo:
Ciò copre probabilmente la maggior parte di ciò che un dipartimento di Business Intelligence farebbe, ad esempio, in SSRS. L'eccezione ovviamente, è qualcosa con $ segni davanti. Molte persone rappresentano denaro con molto più zelo di quello applicato alle metriche chiave correlate necessarie per servire il cliente e generare quel denaro. (Incolpo i ragionieri).
Quando è rischioso
Qualsiasi rapporto che scende al livello di dettaglio. Se tale dettaglio è richiesto, di solito implica che ogni riga sarà rilevante per una decisione. In effetti, se non puoi estrarre un piccolo sottoinsieme senza bloccarlo, potrebbe essere per la buona ragione che è attualmente in fase di modifica.
Dati storici. Raramente fa una differenza pratica, ma mentre gli utenti capiscono che i dati in costante cambiamento non possono essere perfetti, non provano la stessa cosa per i dati statici. Le letture sporche non fanno male qui, ma occasionalmente possono esserlo anche doppie letture. Visto che non dovresti comunque avere blocchi sui dati statici, perché rischiare?
Quasi tutto ciò che alimenta un'applicazione che ha anche capacità di scrittura.
Quando anche lo scenario OK non è OK.
NOLOCK
tali tabelle per nulla.read uncommitted
per le applicazioni Web quando l'utente vede una griglia dell'interfaccia utente in cui l'accuratezza dei dati non è così importante. L'utente vuole solo una rapida panoramica di quali record potrebbero essere presenti, e magari con alcune funzioni di paginazione, ordinamento e filtro. Solo quando l'utente fa clic sul pulsante Modifica, allora provo a leggere il record più recente con un livello di isolamento più rigoroso. Tale approccio non dovrebbe essere migliore in termini di prestazioni?
select item from things with (UPDLOCK)
. Metti un timeout veloce lì in modo che se non riesce ad acquisire il blocco velocemente, dica all'utente che è in fase di modifica. Ciò ti proteggerà non solo dagli utenti ma dagli sviluppatori. L'unico problema qui è che devi iniziare a pensare ai timeout e a come gestirli nell'interfaccia utente.
Per quanto riguarda il reporting, lo utilizziamo su tutte le nostre query di reporting per impedire a una query di bloccare i database. Possiamo farlo perché stiamo estraendo dati storici, non dati aggiornati al microsecondo.
Utilizza READ_UNCOMMITTED in situazioni in cui è altamente improbabile che l'origine cambi.
Non utilizzare READ_UNCOMMITTED quando sai che la souce potrebbe cambiare durante l'operazione di recupero.
READ UNCOMMITTED
.
READ UNCOMMITTED
maggior parte delle situazioni in cui i tuoi dati vengono utilizzati attivamente e vuoi ridurre il carico sul server per evitare possibili deadlock e rollback delle transazioni solo perché alcuni utenti abusano incuratamente " Pulsante "Aggiorna" in una pagina Web con un datagrid. Gli utenti che visualizzano un sacco di record allo stesso tempo, di solito non si preoccupano molto se i dati sono un po 'obsoleti o parzialmente aggiornati. Solo quando un utente sta per modificare un record, potresti voler dargli i dati più accurati.
Questo ti darà letture sporche e ti mostrerà le transazioni che non sono state ancora impegnate. Questa è la risposta più ovvia. Non penso sia una buona idea usarlo solo per velocizzare le tue letture. Esistono altri modi per farlo se si utilizza una buona progettazione di database.
È anche interessante notare cosa non sta succedendo. READ UNCOMMITTED non ignora solo altri blocchi della tabella. Inoltre, non sta causando alcun blocco.
Si consideri che si sta generando un report di grandi dimensioni o che si sta migrando i dati dal database utilizzando un'istruzione SELECT grande e possibilmente complessa. Ciò causerà un blocco condiviso che può essere convertito in un blocco tabella condiviso per la durata della transazione. Altre transazioni possono essere lette dalla tabella, ma gli aggiornamenti sono impossibili. Questa potrebbe essere una cattiva idea se si tratta di un database di produzione poiché la produzione potrebbe interrompersi completamente.
Se si utilizza READ UNCOMMITTED, non verrà impostato un blocco condiviso sulla tabella. È possibile ottenere il risultato da alcune nuove transazioni o non dipendere da dove sono stati inseriti i dati della tabella e da quanto tempo è stata letta la transazione SELECT. È inoltre possibile ottenere gli stessi dati due volte se, ad esempio, si verifica una divisione della pagina (i dati verranno copiati in un'altra posizione nel file di dati).
Quindi, se è molto importante per te che i dati possano essere inseriti mentre fai il tuo SELECT, LEGGI UNCOMMITTED potrebbe avere senso. Devi considerare che il tuo rapporto può contenere alcuni errori, ma se si basa su milioni di righe e solo alcune di esse vengono aggiornate durante la selezione del risultato, questo potrebbe essere "abbastanza buono". La transazione potrebbe anche fallire tutti insieme poiché l'unicità di una riga potrebbe non essere garantita.
Un modo migliore potrebbe essere quello di utilizzare SNAPSHOT ISOLATION LEVEL ma le tue applicazioni potrebbero aver bisogno di alcune modifiche per usarlo. Un esempio di ciò è se l'applicazione utilizza un blocco esclusivo su una riga per impedire ad altri di leggerlo e passare alla modalità di modifica nell'interfaccia utente. SNAPSHOT ISOLATION LEVEL comporta anche una notevole penalità delle prestazioni (soprattutto su disco). Ma puoi superarlo lanciando hardware sul problema. :)
È inoltre possibile prendere in considerazione il ripristino di un backup del database da utilizzare per la creazione di report o il caricamento di dati in un data warehouse.
Può essere utilizzato per una tabella semplice, ad esempio in una tabella di controllo di solo inserimento, in cui non è presente alcun aggiornamento per la riga esistente e non viene visualizzato fk per un'altra tabella. L'inserto è un inserto semplice, che non ha o ha poche possibilità di rollback.
Uso sempre READ UNCOMMITTED ora. È veloce con il minimo numero di problemi. Quando si utilizzano altri isolamenti, si incontrano quasi sempre alcuni problemi di blocco.
Fintanto che usi i campi Incremento automatico e presta un po 'più attenzione agli inserti, allora la tua sanzione, e puoi dire addio ai problemi di blocco.
Puoi fare errori con READ UNCOMMITED ma, a dire il vero, è molto semplice assicurarti che i tuoi inserti siano a prova completa. Inserti / aggiornamenti che utilizzano i risultati di una selezione sono gli unici aspetti a cui devi prestare attenzione. (Utilizzare READ COMMITTED qui o assicurarsi che letture sporche non causino problemi)
Quindi vai su Dirty Reads (Specialmente per grandi report), il tuo software funzionerà più agevolmente ...
Committed
inserimenti e aggiornamenti. Per quanto riguarda altri problemi, ha anche dimostrato la consapevolezza dei problemi di divisione della pagina menzionando l'utilizzo di una chiave di incremento automatico. Concordo con lui sul fatto che quasi tutti i rapporti in diretta fatti leggere solo da un essere umano possono tollerare lievi discrepanze nell'ultimo decimale. Concordo sul fatto che sia una storia diversa per elenchi dettagliati o dati destinati a essere letti e trasformati automaticamente, così come Clive.