Rozszerzanie odpowiedzi Marka ...
Gdy wystąpi limit czasu klienta (na przykład .net CommandTimeout), klient wysyła komunikat „ABORT” do programu SQL Server. Następnie SQL Server po prostu porzuca przetwarzanie zapytania. Żadna transakcja nie jest wycofywana, żadne blokady nie są zwalniane.
Teraz połączenie jest zwracane do puli połączeń, więc nie jest zamykane na SQL Server. Jeśli to się kiedykolwiek zdarzy (poprzez KILL lub restart klienta itp.), Transakcje i blokady zostaną usunięte. Zauważ, że sp_reset_connection ich nie wyczyści lub nie wyczyści, nawet jeśli jest to reklamowane
Ten szczegół po przerwaniu zablokuje inne procesy.
Sposobem na wyczyszczenie transakcji SQL Server + blokowanie limitu czasu klienta (ściśle, zdarzenia ABORT) jest użycie ustawienia SET XACT_ABORT ON.
Możesz to sprawdzić otwierając 2 okna zapytań w SSMS:
Okno 1:
W menu Zapytanie .. Opcje zapytania ustaw limit czasu na 5 sekund, a następnie uruchom go
BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout
Okno 2, będzie czekać wiecznie (lub przekroczy limit czasu)
SELECT * FROM sometable
ZESTAW XACT_ABORT ON ma również interesujące efekty uboczne:
- @@ TRANCOUNT jest ustawiany na zero przy niejawnym wycofaniu, ale błąd 266 jest pomijany (dzieje się tak, jeśli @@ TRANCOUNT jest inny przy wejściu i wyjściu z zapisanego proc)
- XACT_STATE będzie wynosić -1 (jest „skazany”)
Kombinacja tego oznacza, że nie można użyć SAVEPOINTS (chociaż nie pamiętam dokładnego zachowania) do częściowych zatwierdzeń / wycofań. Który mi odpowiada
SO linki na SET XACT_ABORT:
W zagnieżdżonych przechowywanych procesach:
Na sp_reset_connection: