2010-01-13 12 views
14

Sto scrivendo un'applicazione in C# che accede a un database di SQL Server 2005. L'applicazione è abbastanza intensiva per il database e, anche se provo a ottimizzare tutti gli accessi, impostare gli indici appropriati e così via, mi aspetto che prima o poi si verificheranno deadlock. So perché avvengono i deadlock del database, ma dubito che riuscirò a rilasciare il software senza che si verifichino deadlock in un dato momento. L'applicazione utilizza Entity Framework per l'accesso al database.Modelli per la gestione di un deadlock SQL in C#?

Esistono buoni schemi per la gestione di SQLExceptions (deadlocked) nel codice del client C#, ad esempio per rieseguire il batch di istruzioni dopo x millisecondi?

Per chiarire; Non sto cercando un metodo su come evitare deadlock in primo luogo (livelli di isolamento, indici, ordine delle istruzioni, ecc.), Ma piuttosto come gestirli quando si verificano effettivamente.

risposta

4

Ecco l'approccio che abbiamo preso nell'ultimo framework dell'applicazione su cui ho lavorato. Quando abbiamo rilevato un deadlock, abbiamo semplicemente riattivato la transazione. Lo abbiamo fatto fino a 5 volte. Se dopo 5 volte fallisse, faremo un'eccezione. Non ricordo un momento in cui il secondo tentativo abbia mai fallito. Vorremmo sapere perché stavamo registrando tutte le attività nel codice back-end. Quindi sapevamo che in qualsiasi momento si verificava una situazione di stallo e sapevamo se non ci fosse riuscito più di 5 volte. Questo approccio ha funzionato bene per noi.

Randy

+1

Puoi dirmi come hai eseguito l'effettivo riesecuzione della transazione? Hai inserito un semplice ciclo a giro attorno al codice in ogni posto in cui hai avuto una transazione o hai trovato una soluzione più generica? – martin

+1

Abbiamo implementato un ciclo. Se la transazione non è riuscita, a causa di una situazione di deadlock, abbiamo ripristinato l'intera transazione e riprovato fino a 5 volte. –

6

ho postato un esempio di codice per gestire esattamente questo un po 'indietro, ma così sembrò perdere il mio conto nel frattempo, quindi non posso trovare ora ho paura e non hanno la codice che ho usato qui.

Risposta breve: avvolgere la cosa in una prova ... cattura. Se si rileva un errore simile a un deadlock, si può dormire per un breve tempo casuale e incrementare un nuovo tentativo del contatore. Se ottieni un altro errore o il contatore dei tentativi cancella la soglia, riporta l'errore alla routine di chiamata.

(E se è possibile, cercare di bung questo in una routine generale e eseguire la maggior parte/tutti l'accesso DB attraverso di essa deadlock in modo che stai movimentazione-programma di larghezza.)

EDIT: Ah, insegnami non usare Google! Il precedente codice di esempio I e altri ha dato è How to get efficient Sql Server deadlock handling in C# with ADO?