Domanda

Qualcuno può spiegare le implicazioni dell'utilizzo di with (nolock) su query, quando si dovrebbe / non dovrebbe utilizzare?

Per esempio, se si dispone di una domanda di servizi bancari con tassi di transazione elevati e un sacco di dati in alcune tabelle, in quali tipi di query sarebbe nolock essere a posto? Ci sono casi in cui si dovrebbe sempre usare / non usarlo?

È stato utile?

Soluzione

CON (NOLOCK) è l'equivalente di utilizzare LEGGERE UNCOMMITED come un livello di isolamento delle transazioni. Quindi, vi levate in piedi il rischio di leggere una riga commit che viene successivamente il rollback, vale a dire i dati che non ha mai fatto nel database. Così, mentre si può evitare letture di essere in fase di stallo per altre operazioni, si tratta di un rischio. In un'applicazione bancaria con tassi di transazione elevati, probabilmente non sarà la soluzione giusta per qualsiasi problema che si sta cercando di risolvere con esso IMHO.

Altri suggerimenti

La domanda è che cosa è peggio:

  • una situazione di stallo, o
  • un valore errato?

Per i database finanziari, situazioni di stallo sono di gran lunga peggiori di valori errati. So che suona al contrario, ma mi sento fuori. L'esempio classico di transazioni DB è che si aggiorna due file, sottraendo da una e l'aggiunta di un altro. Questo è sbagliato.

In un database finanziario si utilizza transazioni commerciali. Ciò significa aggiungendo una riga a ogni account. E 'della massima importanza che tali operazioni completi e le file sono scritti con successo.

Ottenere il saldo del conto temporaneamente sbagliato non è un grosso problema, che è quello che alla fine della giornata di riconciliazione è per. E uno scoperto da un conto è molto più probabile che si verifichi a causa di due sportelli bancomat sono utilizzati in una sola volta che a causa di una lettura uncommitted da un database.

Detto questo, SQL Server 2005 fissato la maggior parte dei bug che hanno reso NOLOCK necessario. Quindi, a meno che non si utilizza SQL Server 2000 o versioni precedenti, non dovrebbe essere necessario esso.

Bibliografia
a livello di riga delle versioni

L'esempio libro di testo per l'uso legittimo della hint NOLOCK è verbale di prelievo nei confronti di un database ad alte aggiornamento OLTP.

Per fare un esempio di attualità. Se una grande banca high street US voleva eseguire un rapporto orario alla ricerca dei primi segni di un percorso a livello di città, sulla riva, una query nolock potrebbe eseguire la scansione di tabelle di transazione che riassumono depositi in contanti e prelievi di contante per città. Per tale relazione la piccola percentuale di errore causato da rollback transazioni di aggiornamento non ridurrebbe il valore del rapporto.

Purtroppo non si tratta solo di lettura dei dati non impegnati. Sullo sfondo si può finire la lettura di pagine per due volte (nel caso di una divisione di pagina), o si può perdere le pagine del tutto. Quindi, i risultati possono essere grossolanamente distorta.

Scopri articolo Itzik Ben-Gan . Ecco un estratto:

  

" Con l'hint NOLOCK (o impostando la   livello di isolamento della sessione per LEGGERE   UNCOMMITTED) dici di SQL Server che   che non ti aspetti di coerenza, quindi non c'è   sono garanzie. Tenete a mente però   che "i dati incoerente" non si limita   significa che si potrebbe vedere impegnati   modifiche che sono state in seguito il rollback,   o modifiche dei dati in un intermedio   stato della transazione. E 'anche   significa che in una semplice query che   analizza tutti i tabella / indice di SQL Server dati   può perdere la posizione di scansione, oppure   potrebbe finire per ottenere la stessa riga   due volte . "

Non certo perché non si sta avvolgendo le transazioni finanziarie in operazioni di database (come quando si trasferiscono fondi da un conto ad un altro - tu non commetti un lato della transazione at-a-tempo - questo è il motivo per cui esistono le transazioni esplicite) . Anche se il codice è braindead per transazioni commerciali come sembra come esso è, tutti i database transazionali hanno il potenziale per fare rollback impliciti in caso di errori o guasti. Credo che questa discussione è il modo sopra la vostra testa.

Se si hanno problemi di bloccaggio, implementare il controllo delle versioni e ripulire il codice.

Nessun blocco non solo restituisce valori errati restituisce record fantasma e duplicati.

Si tratta di un malinteso comune che si fa sempre più veloci le query. Se non ci sono blocchi di scrittura su un tavolo, non fa alcuna differenza. Se ci sono le serrature sul tavolo, può rendere la query più veloce, ma c'è una ragione serrature sono state inventate in primo luogo.

In tutta onestà, qui ci sono due scenari particolari in cui un suggerimento NOLOCK può fornire utility

1) di database di SQL Server pre-2005, che ha bisogno di correre lungo query di database OLTP dal vivo questo può essere l'unico modo

2) applicazione scritti male che blocca record e restituisce il controllo l'interfaccia utente e lettori sono a tempo indeterminato bloccati. Nolock può essere utile qui se l'applicazione non può essere risolto (di terze parti, ecc) e il database si sia pre-2005 o delle versioni non possono essere accesi.

NOLOCK è equivalente a READ UNCOMMITTED, tuttavia Microsoft dice che non si dovrebbe usare per le dichiarazioni UPDATE o DELETE:

  

Per UPDATE o DELETE: Questa funzionalità verrà rimossa in una versione futura di Microsoft SQL Server. Evitare di utilizzare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica delle applicazioni che utilizzano questa funzione.

http://msdn.microsoft.com/en-us/library/ ms187373.aspx

In questo articolo si applica a SQL Server 2005, in modo che il supporto per NOLOCK esiste se si utilizza quella versione. Al fine di codice a prova di futuro si (supponendo che hai deciso di utilizzare letture dirty) si potrebbe usare questo nella stored procedure:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Si può usare quando si è solo la lettura dei dati, e non si ha realmente preoccuparsi se o non si potrebbe ottenere indietro i dati non ancora impegnata.

Si può essere più veloce su un'operazione di lettura, ma non posso davvero dire di quanto.

In generale, mi raccomando contro usarlo -. La lettura dei dati non impegnati può essere un po 'di confusione al meglio

Un altro caso in cui di solito è a posto è in un database di report, in cui i dati è forse già invecchiato e scrive semplicemente non accadrà. In questo caso, però, l'opzione deve essere impostata a livello di database o la tabella dall'amministratore modificando il livello di isolamento predefinito.

Nel caso generale: si può utilizzare quando si è molto sicuro che è bene leggere i vecchi dati. La cosa importante da ricordare è che il suo molto facile da ottenere che sbagliato . Ad esempio, anche se va bene, al momento si scrive la query, sei sicuro qualcosa non cambierà nel database in futuro per rendere questi aggiornamenti più importante?

Sarò anche secondo la nozione che è probabilmente non una buona idea in App bancario. O App inventario. O dovunque stai pensando di transazioni.

Risposta semplice -. Ogni volta che lo SQL non è alterare i dati, e si dispone di una query che potrebbe interferire con altre attività (tramite bloccaggio)

E 'da prendere in considerazione per qualsiasi query utilizzate per i report, soprattutto se la query richiede più rispetto, ad esempio, 1 secondo.

E 'particolarmente utile se si dispone di report OLAP-tipo si sta eseguendo in un database OLTP.

Il prima domanda da porsi, però, è "perché sto preoccupando di questo?" ln mia esperienza, fudging il comportamento di blocco predefinito spesso avviene quando qualcuno è in modalità "provare di tutto" e questo è un caso in cui conseguenze inaspettate non è improbabile. Troppo spesso si tratta di un caso di ottimizzazione prematura e può troppo facilmente ottenere sinistro incorporato in un'applicazione "just in case". E 'importante capire il motivo per cui si sta facendo, che problema si risolve, e se effettivamente avere il problema.

I miei 2 centesimi - ha senso utilizzare WITH (NOLOCK) quando è necessario per generare report. A questo punto, i dati non cambierebbero molto e che non vorrebbe bloccare i record.

Se si sta gestendo operazioni di finanza poi non vorrete utilizzare nolock. nolock è meglio utilizzato per selezionare tabelle di grandi dimensioni che dispongono di aggiornamenti lotti e non importa se il record si ottiene potrebbe non essere aggiornato.

Per i record finanziari (e quasi tutti gli altri record in gran parte delle applicazioni) nolock sarebbe devastare come si potrebbe leggere i dati di ritorno da un record che è stato in fase di scrittura e non ottenere i dati corretti.

Ho usato per recuperare un "lotto successivo" cosa c'è da fare. Non importa in questo caso, che oggetto esatto, e ho un sacco di utenti che eseguono questa stessa query.

Risposta breve:

Non usare mai WITH (NOLOCK).

Risposta lunga:

NOLOCK viene spesso sfruttata come un modo magico per accelerare database di legge, ma cerco di evitare di utilizzare per quanto possibile.

Il set di risultati può contenere le righe che non sono ancora stati commessi, che sono spesso in seguito rollback.

Un errore o Risultato-set può essere vuoto, essere righe mancanti o mostrano la stessa riga più volte.

Questo è perché le altre operazioni si stanno muovendo i dati allo stesso tempo si sta leggendo.

READ COMMITTED aggiunge un ulteriore problema in cui i dati sono danneggiati all'interno di una singola colonna in cui più utenti modificano la stessa cella contemporaneamente.

Ci sono altri effetti collaterali troppo, che si traducono in sacrificare la velocità aumenta che speravano di ottenere, in primo luogo.

Si può sostenere che è bene usare in luoghi dove è possibile ottenere via con esso, ma qual è il punto? Non riesco a pensare di qualsiasi situazione in cui i dati danneggiati è accettabile.

Non utilizzare mai NOLOCK mai.

(sempre)

Usa nolock quando si sta bene con i dati "sporchi". Il che significa nolock può leggere i dati che è in corso di modifica o di dati e / non impegnati.

Non è generalmente una buona idea di utilizzare in ambiente ad alta transazione ed è per questo che non è un opzione di default su richiesta.

Io uso con (nolock) suggerimento particolare in SQLServer 2000 basi di dati ad alta attività. Io non sono sicuro che è necessario in SQL Server 2005 tuttavia. Recentemente ho aggiunto quel pizzico in SQL Server 2000, su richiesta del DBA del cliente, perché stava notando un sacco di SPID blocchi di record.

Tutto quello che posso dire è che utilizzando l'hint non ha fatto del male a noi e sembra aver reso il problema di blocco si risolve. Il DBA in quel particolare client in sostanza ha insistito che usiamo il suggerimento.

Tra l'altro, le basi di dati mi occupo sono back-end ai sistemi di attestazioni mediche aziendali, quindi stiamo parlando di milioni di dischi e 20 + tabelle in molti join. Io di solito aggiungo un (nolock) suggerimento per ogni tabella nel join (a meno che non si tratta di una tabella derivata, nel qual caso non è possibile utilizzare quel particolare suggerimento)

La risposta più semplice è una semplice domanda - hai bisogno i risultati a essere ripetibile? Se sì allora NOLOCKS non è appropriato in nessun caso

Se non avete bisogno di ripetibilità poi nolocks possono essere utili, soprattutto se non si ha il controllo su tutti i processi che si connettono al database di destinazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top