Расширяя ответ Марка ...
Когда происходит событие тайм-аута клиента (например, .net CommandTimeout), клиент отправляет «ABORT» на SQL Server. SQL Server просто прекращает обработку запросов. Откат транзакции не производится, блокировки не снимаются.
Теперь соединение возвращается в пул соединений, поэтому оно не закрывается на SQL Server. Если это произойдет (через KILL или перезагрузку клиента и т. Д.), Транзакции + блокировки будут очищены. Обратите внимание, что sp_reset_connection не будет или не очищает их, даже если это было объявлено
Этот детрит от аборта заблокирует другие процессы.
Чтобы сделать SQL Server четкими транзакциями + блокировки по тайм-ауту клиента (строго, события ABORT), используйте SET XACT_ABORT ON.
Вы можете проверить это, открыв 2 окна запроса в SSMS:
Окно 1:
В меню Query..Query Options установите время ожидания 5 секунд, затем запустите
BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout
Окно 2, это будет ждать вечно (или истечет время ожидания)
SELECT * FROM sometable
У SET XACT_ABORT ON также есть интересные побочные эффекты:
- При неявном откате @@ TRANCOUNT устанавливается равным нулю, но ошибка 266 подавляется (это происходит, если @@ TRANCOUNT отличается при входе и выходе из сохраненного процесса)
- XACT_STATE будет -1 (это «обречено»)
Комбинация этого означает, что вы не можете использовать SAVEPOINTS (хотя я не могу вспомнить точное поведение) для частичных фиксаций / откатов. Который мне подходит
ТАК ссылки на SET XACT_ABORT:
На вложенных хранимых процессах:
На sp_reset_connection: