Deadlock

martedì 10 agosto 2010 - 08.20

dompa72 Profilo | Senior Member

Ogni tanto si presenta questo errore:
Messaggio = La transazione (ID di processo 54) è stata interrotta a causa di un deadlock delle risorse blocco con un altro processo. Ripetere la transazione.
Sorgente = .Net SqlClient Data Provider

naturalmente id è diverso.

La transazione è ReadCommitted

questo avvieme al 95% dei casi su un update ed il 5% su un insert le tabelle sono due (questo complica un po le cose).
la cosa strana che quel record lo può modificare solo un utente per volta però lo possono leggere tutti.
Per questo motivo ho modificato il metodo di accesso in lettura con lo snapshot (questo l'ho fatto questa mattina).
Questa modifica non mi convince perchè è solo una "PEZZA" al problema
Come faccio a vedere i log della transazione che si è interrotta e soprattutto la query che blocca i record???

Scusate ma sono per la prima volta preso da un progetto con 400 persone che si connettono al db (per fortuna non in simultanea)

Grazie

lbenaglia Profilo | Guru

>Come faccio a vedere i log della transazione che si è interrotta
>e soprattutto la query che blocca i record???

Ciao,

Lancia una sessione con il Profiler catturando gli eventi Deadlock graph, Lock:Deadlock e Lock:Deadlock Chain che trovi sotto Locks.
Per maggiori info leggi questo paragrafo dei BOL:
http://msdn.microsoft.com/en-us/library/ms188246.aspx

>Scusate ma sono per la prima volta preso da un progetto con 400
>persone che si connettono al db (per fortuna non in simultanea)
Generalmente i deadlock sono causati dal fatto che procedure accedono in lettura e scrittura a 2 o più oggetti in ordine inverso all'interno di una transazione esplicita.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

TomClancy Profilo | Junior Member

Io uso anche SP_lock per avere maggiori info sullo spid e l'oggetto che blocca. ( attenzione che nelle prox release verrà deprecato )

http://msdn.microsoft.com/it-it/library/ms187749.aspx

dompa72 Profilo | Senior Member

Ho avviato la sessione di tracciatura fino a domani ore 12.
Considera che questa tabella ha 50000 transazioni circa, il problema di deadlock al massimo 5 al giorno (molte volte mai). Nella funzione ho messo che in caso di errore genera una nuova transazione per un massimo di 5 volte, e qui la cosa si fa interessante, non è mai successo che a seguito dell'errore si sia rigenerato il deadlock alla successiva transazione.

Il mio problema

dompa72 Profilo | Senior Member

i primi due deadlock.
Per il primo non ho capito nulla, infatti come posso risalire alla query che ha bloccato il tutto?
Per il secondo dove risulta una chiave primaria, posso solo dire che la transazione si blocca su una tabella che non ha quella chiave primaria e questo aumenta la gravità

Grazie

dompa72 Profilo | Senior Member

per TomClancy
anche questa può essere una soluzione, ma non penso di implementarla considerando che forse a gennaio passiamo alla versione 2008

Grazie

lbenaglia Profilo | Guru

>Per il primo non ho capito nulla, infatti come posso risalire
>alla query che ha bloccato il tutto?

Apri i file in SSMS con un doppio click, seleziona col mouse uno dei due "cerchi" ed il tooltip ti visualizzerà il comando eseguito quando si è verificato il deadlock.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dompa72 Profilo | Senior Member

Grazie per l'aiuto, ma i conti non mi tornano.
la chiave primaria sta nella tabella del select, l'altra tabella non ha chiavi primarie
Il database non usa tabelle relazionate. le query visualizzate sono di tabelle diverse....cosa mi sfugge????
Un aiuto dall'esperienza

lbenaglia Profilo | Guru

>Grazie per l'aiuto, ma i conti non mi tornano.

deadlock_1.xld
------------------
Le due sessioni stanno cercando di aggiornare contemporaneamente la tabella ODLOperSucc.
La sessione 119 richiede un Update Lock sulla pagina 51919 che è bloccata in modo esclusivo dalla sessione 94; la sessione 94 richiede un Update Lock alla pagina 191725 che è bloccata in modo esclusivo dalla sessione 119.
La transazione della sessione 119 viene annullata.


deadlock_2.xld
------------------
Che oggetto è quello coinvolto nel RID Lock?
Interroga la tabella sys.objects

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dompa72 Profilo | Senior Member

Sembra che non ci sia, ti allego il risultato della query.

E' possibile mettere un blocco per record e non per pagina??? se si cosa cambia???

Grazie dell'aiuto.

lbenaglia Profilo | Guru

>E' possibile mettere un blocco per record e non per pagina???
>se si cosa cambia???
SQL Server attiva di default dei lock a livello di riga e scala automaticamente a livello di pagina, tabella o db nel caso si renda necessario (ad es. non ha senso mantenere centinaia di lock per righe consecutive quando puoi locckare direttamente le pagine che le contengono).

Se forzi una certa tipologia di lock potresti peggiorare drasticamente le performance.

>Grazie dell'aiuto.
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dompa72 Profilo | Senior Member

Ma come posso verificare che un record è momentaneamente bloccato?
In questo momento la funzione tenta di completare la transazione per 5 volte prima di bloccarsi visualizzando un messaggio di errore.
Non penso che sia la scelta migliore, ma per il momento non vedo alternative. Non posso permettermi di rallentare le performance.

Grazie di tutto.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5