SET XACT_ABORT określa, jaką akcję silnik SQL Server powinien wykonać po wystąpieniu błędów wykonań w ramach sesji. Domyślne ustawienie sesji to SET XACT_ABORT OFF, co wskazuje, że tylko instrukcja języka Transact-SQL, która zgłosiła błąd, jest wycofywana, a transakcja jest kontynuowana. W zależności od wagi błędu cała transakcja i/lub partia może zostać wycofana, nawet jeśli SET XACT_ABORT jest WYŁĄCZONE.

Efektem ubocznym SET XACT_ABORT OFF jest to, że błąd anulowania/przekroczenia limitu czasu może pozostawić otwartą transakcję, więc to klient jest odpowiedzialny za oczyszczenie po anulowaniu/przekroczeniu limitu czasu. Aby zabezpieczyć się przed pozostawieniem otwartej transakcji, aplikacje wykonujące transakcje z SET XACT_ABORT OFF muszą wycofać transakcje i być może zamknąć połączenie po wystąpieniu wyjątków SQL.

Należy zauważyć, że w przypadku puli połączeń po prostu zamknięcie połączenia bez wycofywania zwróci tylko połączenie do puli, a transakcja pozostanie otwarta do późniejszego ponownego użycia lub usunięcia z puli. Może to spowodować, że blokady zaczną być niepotrzebnie utrzymywane i spowodować inne limity czasu i blokady.

SET XACT_ABORT ON instruuje SQL Server, aby wycofał całą transakcję i przerwał partię, gdy wystąpi błąd w czasie wykonywania. SET XACT_ABORT nie ma wpływu na błędy kompilacji (np. błędy składni).

SET XACT_ABORT ON zapewnia pożądane zachowanie w większości przypadków i jest zalecane uwzględnienie tej opcji we wszystkich procedurach składowanych z jawnymi transakcjami.

SET XACT_ABORT ON jest nadal potrzebne z obsługą błędów strukturalnych. Kiedy używasz XACT_ABORT z obsługą błędów strukturalnych, powinieneś sprawdzić XACT_STATE() w bloku CATCH, aby określić, czy COMMIT/ROLLBACK jest możliwy.

XACT_ABORT zmienia zachowanie obsługi błędów, ale nie zmienia blokowania, gdy nie określono jawnej transakcji. Bez jawnej transakcji każda instrukcja znajduje się w pojedynczej transakcji, która zostanie zatwierdzona lub wycofana po zakończeniu instrukcji (pomyślnie lub nie), niezależnie od ustawienia XACT_ABORT. Myślę, że jedyną zaletą XACT_ABORT bez jawnej transakcji jest to, że może zapobiec kontynuowaniu pozostałej części procedury po błędzie, nawet jeśli nie zawiera kodu obsługi błędów

Jeśli dla przykładu utworzymy tabelę dbo.Foo z jedną kolumną ID, która jest elementem klucza głównego i wykonamy następujący kod:

begin transaction
insert into dbo.Foo (ID) values(1);
insert into dbo.Foo (ID) values(1);
commit transaction;

To zauważymy, że przy kolejnym insercie wygeneruje się błąd,ponieważ klucz główny musi być unikalny. Jeśli skontrolujemy zawartość tabeli oto przekonamy się, że wartośćz pierwszego insert’a została dodana(1). Dzieje się to dlatego ponieważ domyślnie transakcja nie jest anulowana w przypadku wystąpienia błędu. Aby temu zaradzić należy ustawić właśnie zmienną XACT_ABORT na true:

SET XACT_ABORT ON

begin transaction
insert into dbo.Foo (ID) values(1);
insert into dbo.Foo (ID) values(1);
commit transaction;

SET XACT_ABORT ON spowoduje, że w przypadku wystąpienia błędu cała transakcja jest anulowana (rollback). W tabeli nie ma dodanych rekordów.


Dariusz Brejnak

Od prawie trzydziestu lat jest pasjonatem informatyki, a zwłaszcza dziedzin dotyczących baz danych, hurtowni danych oraz ogólnie rozumianej tematyki BI. Jego druga pasja to fotografia http://dariuszbrejnak.pl