2012-05-24 2 views
9

Ho una tabella in SQL Server che è CRUD-ed contemporaneamente da una stored procedure in esecuzione contemporaneamente in diverse sessioni:È possibile aggiungere una colonna Identity chiave primaria per risolvere problemi di deadlock?

|----------------|---------|
| <some columns> | JobGUID |
|----------------|---------|

la procedura funziona nel modo seguente:

  1. Genera un GUID.
  2. inserire alcuni record nella tabella condivisa sopra descritta, contrassegnandoli con il GUID dal punto 1.
  3. Eseguire alcuni aggiornamenti su tutti i record dal punto 2.
  4. selezionare i record dal punto 3 come uscita SP.

Ogni selezionare/inserimento/aggiornamento/DELETE nella stored procedure ha una clausola WHERE JobGUID = @jobGUID, quindi la procedura funziona solo con i record che ha inserito il punto 2. Tuttavia, a volte, quando la stessa stored procedure viene eseguito in parallelo in diverse connessioni, si verificano deadlock sulla tabella condivisa. Ecco il grafico deadlock da SQL Server Profiler:

SQL Server Profiler Deadlock Graph

escalation dei blocchi non si verificano. Ho provato ad aggiungere suggerimenti di blocco (UPDLOCK, ROWLOCK) a tutte le istruzioni DML e/o ad avvolgere il corpo della procedura in una transazione e utilizzando diversi livelli di isolamento, ma non è stato di aiuto. Ancora lo stesso blocco RID sul tavolo condiviso.

Successivamente ho scoperto che la tabella condivisa non aveva una colonna chiave/identità primaria. E una volta ho aggiunto, deadlock sembrano essere scomparsi:

alter table <SharedTable> add ID int not null identity(1, 1) primary key clustered 

Quando ho rimuovere la colonna chiave primaria, i punti morti sono tornati. Quando lo aggiungo, non riesco più a riprodurre il deadlock.

Quindi, la domanda è, una colonna di identità chiave primaria è davvero in grado di risolvere deadlock o è solo una coincidenza?

Aggiornamento: come @Catcall suggerisce, ho cercato di creare una chiave naturale cluster primaria sulle colonne esistenti (senza l'aggiunta di una colonna di identità), ma ancora preso la stessa situazione di stallo (ovviamente, questa volta è stato un tasto bloccare invece del blocco RID).

+0

è la colonna GUID indicizzati? –

+0

@MartinSmith: Sì, ha un indice non univoco non cluster. –

+0

Quale livello di isolamento della transazione sono gli SP in esecuzione? –

risposta

4

La migliore risorsa (ancora) per la risoluzione deadlock è qui: http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx.

Pt # 4 dice:

Eseguire le query coinvolte nella situazione di stallo attraverso database Ottimizzazione Advisor. Ritirare la query in una finestra di query di Management Studio, modificare il contesto db nel database corretto, fare clic con il tasto destro del mouse sul testo della query e selezionare selezionare "Analizza query in DTA". Non saltare questo passaggio; più della metà dello dei problemi di deadlock che vediamo sono risolti semplicemente aggiungendo un indice appropriato in modo che una delle query venga eseguita più rapidamente e con un footprint di blocco inferiore.Se la DTA consiglia gli indici (verrà detto "Miglioramento stimato:%"), crearli e monitorare su vedere se il deadlock persiste. È possibile selezionare "Applica suggerimenti" dal menu a discesa Azione per creare immediatamente l'indice oppure salvare i comandi CREATE INDEX come uno script per crearli durante una finestra di manutenzione . Assicurati di sintonizzare separatamente ciascuna query.

So che questo non "risposta" alla domanda sul motivo per cui necessariamente, ma tuttavia esse indicano che l'aggiunta degli indici può cambiare l'esecuzione in modo di dare sia l'impronta di blocco più piccolo o tempo di esecuzione più veloce che può ridurre in modo significativo il possibilità di un punto morto.

1

Recentemente ho visto questo post, in base alle informazioni di cui sopra Spero che questo post vi aiuterà,

http://databaseusergroup.blogspot.com/2013/10/deadlocked-on-sql-server.html

+1

Nota che [risposte solo per collegamento] (http://meta.stackoverflow.com/tags/link-only-answers/info) sono scoraggiate, pertanto le risposte dovrebbero essere il punto finale di una ricerca di una soluzione (vs. ancora un altro scalo di riferimenti, che tendono a diventare stantii nel tempo). Si prega di considerare l'aggiunta di una sinossi autonoma qui, mantenendo il collegamento come riferimento. – kleopatra