È necessario indagare sul lato server per capire perché il timeout di esecuzione è scaduto. Tieni presente che il server non ha timeout, il timeout è causato dai 30 secondi predefiniti su SqlCommand.CommandTimeout
.
Una buona risorsa è Attese e code , che è una metodologia per diagnosticare i colli di bottiglia delle prestazioni con SQL Server. In base alla causa effettiva del timeout, è possibile intraprendere un'azione adeguata. Devi stabilire prima di tutto se hai a che fare con un'esecuzione lenta (un piano sbagliato) o un blocco.
Se dovessi azzardare un'ipotesi, direi che lo schema malsano di IF EXISTS... UPDATE
è la causa principale. Questo modello non è corretto e causerà errori in simultanea. Due transazioni simultanee che eseguono IF EXISTS
simultaneamente raggiungeranno entrambi la stessa conclusione e entrambi prova a INSERT
o UPDATE
. A seconda dei vincoli esistenti nel database, puoi finire con un deadlock (il caso fortunato) o con una scrittura persa (il caso sfortunato). Tuttavia, solo un'indagine adeguata rivelerebbe la vera causa principale. Potrebbe essere qualcosa di completamente diverso, come eventi di crescita automatica
.
Anche la tua procedura sta gestendo in modo errato il blocco CATCH. Devi sempre controlla XACT_STATE()
perché la transazione potrebbe essere già stata annullata prima dell'esecuzione del blocco CATCH. Inoltre, non è chiaro cosa ti aspetti dal nominare la transazione, questo è un errore comune che vedo spesso associato alla confusione delle transazioni denominate con i punti di salvataggio. Per uno schema corretto, vedere Gestione delle eccezioni e transazioni nidificate .
Modifica
Ecco un possibile modo per indagare su questo:
- Modifica il
CommandTimeout
a 0 (cioè infinito). - Abilita la
blocked process threshold
, impostalo su 30 secondi (il precedente CommandTimeout) - Monitoraggio in Profiler per Evento rapporto processo bloccato
- Inizia il tuo carico di lavoro
- Vedi se il Profiler produce eventi di report. In tal caso, individueranno la causa.
Queste azioni causeranno un evento di "report di processo bloccato" ogni volta che avresti avuto un timeout, se il timeout fosse causato dal blocco. L'applicazione continuerà ad attendere fino alla rimozione del blocco, se il blocco è causato da un blocco live allora aspetterà per sempre.