2011-07-21 23 views
8

Quindi, a quanto ho capito, i deadlock SQL si verificano quando uno SPID è impegnato a elaborare un'altra query e non può essere disturbato a eseguirne un altro perché è così occupato in questo momento. SQL Server "casualmente" seleziona una delle query per deadlock delle risorse richieste e fallisce, generando un'eccezione.Perché i deadlock si verificano in SQL Server?

Ho un'app in esecuzione ~ 40 istanze e un servizio Windows back-end, che stanno tutti colpendo lo stesso database. Sto cercando di ridurre i deadlock in modo da poter aumentare il numero di thread che posso eseguire contemporaneamente.

  1. Perché SQL Server non può semplicemente accodare la nuova query ed eseguirla quando ha tempo e le risorse sono disponibili? La maggior parte di quello che sto facendo può aspettare qualche secondo in occasione.
  2. C'è un modo per impostare il livello di isolamento a livello globale senza doverlo specificare all'inizio di ogni nuova connessione/sessione?
+8

La tua definizione di 'deadlock' non è corretto. Normalmente SQL Server ** fa ** aspetta altre richieste. Quando uccide una query perché rileva una condizione di deadlock è perché la serie di query specificata non può essere completata (mai) e qualcuno deve perdere. Penso che se fai un po 'di lettura su quali sono i deadlock, ti ​​troverai in una posizione molto migliore per ottenere il valore da una domanda migliore –

+7

"Così come la capisco" ... il resto di quel paragrafo è praticamente errato . – heisenberg

+1

I deadlock non hanno nulla a che fare con il server che è troppo occupato per soddisfare una richiesta. Ti suggerisco di ripubblicare la tua domanda o di andare a vedere che cos'è un deadlock. – sqlvogel

risposta

18

La tua comprensione dei deadlock non è corretta. Quello che hai descritto è il blocco. È un errore comune equiparare i due.

Un deadlock si verifica quando due transazioni separate richiedono risorse diverse e nessuno dei due rilascerà quello che hanno in modo che l'altro possa essere eseguito. E 'probabilmente più facile per illustrare:

SPID # 1 ottiene un blocco sulla risorsa A SPID # 2 ottiene un blocco sulla risorsa B SPID # 1 ora ha bisogno di un blocco sulla risorsa B, al fine di completare SPID # 2 ora ha bisogno un blocco sulla risorsa A per completare

SPID n. 1 non può completare (e quindi la risorsa di rilascio A) perché SPID n. 2 lo ha SPID n. 2 non può completare (e quindi liberare B) perché SPID # 1 ce l'ha

Poiché nessuno SPID può completarne uno deve rinunciare (cioè essere scelto dal server come vittima del deadlock) e fallirà.

Il modo migliore per evitarli è mantenere le transazioni piccole (in numero di risorse necessarie) e veloci.

+4

(+1) Immagina due macchine dirette l'una verso l'altra su una strada a corsia unica. Entrambi hanno bisogno della strada per continuare, ma ovviamente non possono averli entrambi, a meno che una macchina non si arresti o scompaia (ad esempio "rollback"). Nessuna quantità di attesa, memoria, disco, ecc. Può essere d'aiuto –

+0

Gli SPID in questione non eseguono nemmeno transazioni corrette; solo dichiarazioni CRUD semplici. Devo specificare unsmitted su ognuno di essi? In genere la mia app aprirà e chiuderà una connessione per ogni istruzione/query, a meno che non debba fare un mucchio di righe. Ma si sommano su n thread e x utenti. Ogni statement/query (di quelli che sono in modalità deadlock) richiede solo circa 50-200ms da eseguire. – tsilb

+0

@tsilb potresti trovare questa utility ['aba_lockinfo'] (http://www.sommarskog.se/sqlutil/aba_lockinfo.html) molto utile –

3

Deadlock è il punto in cui due thread di elaborazione vengono entrambi trattenuti dall'altro (può essere più, ma due è sufficientemente complesso). Quindi un thread blocca una tabella, quindi richiede un blocco su un'altra tabella. l'altra tabella è bloccata dal secondo thread, che non può progredire perché è in attesa di un blocco sulla prima tabella.

Il motivo per cui uno di questi deve essere eliminato è che in una situazione di stallo, non finiranno mai - nessuno dei due thread può progredire del tutto. L'unica risposta è che uno si fermi per consentire all'altro di completare.

La soluzione per ridurre i deadlock nel tipo di situazione di cui si parla potrebbe essere la riprogettazione della soluzione. Se è possibile assicurarsi che si verifichi meno blocchi, si avranno meno deadlock.

1

I deadlock si verificano perché, due transazioni simultanee possono sovrapporsi a bloccare diverse risorse, entrambe richieste dall'altra transazione per completare.

Immaginiamo: 1 - Transaction blocca un row1 2 - Transaction serrature B row2 3 - Transaction Una prova a bloccare row1, e, a causa del blocco precedente, SQL server attende 4 - Transaction B prova a bloccare riga2 e, a causa del blocco precedente, SQL Server attende

Quindi, il server SQL deve scegliere sulla transazione, eliminarlo e consentire all'altro di continuare.

Questa immagine illustra questa situazione molto bene: http://www.eupodiatamatando.com/wp-content/uploads/2008/01/deadlocknajkcomafarialibh3.jpg

Problemi correlati