Timeout transazione SQL Server


9

Esiste un modo in SQL Server 2008 R2 per causare un timeout per una modifica del database che coinvolge una transazione? Abbiamo uno scenario in cui il nostro codice dell'applicazione si blocca o genera un'eccezione e non riesce a eseguire un rollback o un commit. Ciò causa quindi l'attesa di altre sessioni in attesa del completamento della transazione.

Risposte:


20

Estensione della risposta di Mark ...

Quando si verifica un evento di timeout del client (ad esempio .net CommandTimeout), il client invia un "ABORT" a SQL Server. SQL Server quindi abbandona semplicemente l'elaborazione della query. Non viene eseguito il rollback di alcuna transazione, non vengono rilasciati blocchi.

Ora, la connessione viene restituita al pool di connessioni, quindi non è chiusa su SQL Server. Se ciò dovesse accadere (tramite KILL o riavvio del client, ecc.) Le transazioni + i blocchi verranno cancellati. Nota che sp_reset_connection non li cancella o non li cancella, anche se è pubblicizzato per farlo

Questo detrito dall'interruzione bloccherà altri processi.

Il modo per rendere trasparenti le transazioni + i blocchi di SQL Server sul timeout del client (rigorosamente, eventi ABORT) è utilizzare SET XACT_ABORT ON.

È possibile verificare che questo apra 2 finestre di query in SSMS:

Finestra 1:

Nel menu Query..Query Options imposta un timeout di 5 secondi quindi esegui questo

BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout

Finestra 2, questo attenderà per sempre (o raggiungerà il timeout)

SELECT * FROM sometable

SET XACT_ABORT ON ha anche effetti collaterali interessanti:

  • @@ TRANCOUNT è impostato su zero sul rollback implicito ma l'errore 266 viene eliminato (ciò accade se @@ TRANCOUNT è diverso all'entrata e all'uscita da un proc memorizzato)
  • XACT_STATE sarà -1 (è "condannato")

La combinazione di questo significa che non è possibile utilizzare SAVEPOINTS (anche se non ricordo il comportamento esatto) per commit / rollback parziali. Che mi va bene

Collegamenti SO su SET XACT_ABORT:

Su proc memorizzati nidificati:

Su sp_reset_connection:


Il futuro dice ciao! "Nota che sp_reset_connection non li cancella o non li cancella, anche se è pubblicizzato per farlo" - Non credo che questo sia più vero nelle versioni aggiornate di SQL Server?
kamilk,

11

Sto rispondendo con esitazione perché non ci sono abbastanza informazioni nella descrizione del problema per essere sicuri al 100% che questo sia il miglior consiglio. "Blocca o genera un'eccezione" suggerisce che l'origine del problema non è stata compresa correttamente, quindi procedi con cautela.

La soluzione più semplice a questo è probabilmente SET XACT_ABORT ON.

XACT_ABORTdetermina se SQL Server eseguirà il rollback di una transazione in caso di errore di runtime. Il valore predefinito SET XACT_ABORT OFFeseguirà il rollback solo dell'istruzione che ha causato un errore, lasciando aperta qualsiasi transazione principale.

L'effetto collaterale "gotcha" dell'impostazione predefinita è che un timeout può causare esattamente lo stesso problema, una transazione aperta che è la responsabilità dei clienti di gestire e ripristinare. Se il cliente non prova / cattura / rollback, la transazione rimarrà aperta fino a quando non verrà seguita (e cito @gbn) l'ultra violenza di KILL <spid>.

Gli articoli di Erland Sommarskog citati spesso sulla gestione degli errori in SQL Server contengono tutto lo sfondo e la strategia necessari per gestire questi scenari e altro ancora.

Modifica (seguente commento): per identificare le transazioni aperte, sp_whoisactive è probabilmente la funzionalità più completa.


Ho trovato su Google alcuni modi per trovare transazioni aperte quando si verifica l'arresto: forse questa è la soluzione migliore. Cioè per scoprire qual è la causa della transazione non chiusa nel codice e correggere i buchi nel codice. Per riferimento per gli altri. DBCC OPENTRAN restituisce la transazione attiva più vecchia -> msdn.microsoft.com/en-us/library/ms182792.aspx O qualcosa di più simile a questo? -> weblogs.sqlteam.com/mladenp/archive/2008/04/29/…
David Gray Wright,

Ho sempre pensato che Erland non rendesse
gbn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.