Jaka jest zaleta używania opcji „SET XACT_ABORT ON” w procedurze składowanej?


Jaka jest zaleta używania
SET XACT_ABORT ON

w procedurze składowanej?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

SET XACT_ABORT ON
instruuje SQL Server, aby wycofał całą transakcję i przerwał partię, jeśli wystąpi błąd w czasie wykonywania. Obejmuje to przypadki, takie jak przekroczenie limitu czasu polecenia występujące w aplikacji klienckiej, a nie w samym serwerze SQL (co nie jest objęte domyślnym ustawieniem
XACT_ABORT OFF
).
Ponieważ limit czasu żądania pozostawia transakcję otwartą,
SET XACT_ABORT ON
jest zalecane dla wszystkich jawnych procedur składowanych transakcji (chyba że masz konkretny powód, aby zrobić inaczej), jako implikacje aplikacji pracującej na otwartej transakcji połączenie są katastrofalne.
W

Blog Dana Guzmana
http://weblogs.sqlteam.com/dan ... .aspx
jest naprawdę świetny przegląd,
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Moim zdaniem SET XACT_ABORT ON został uznany za przestarzały z powodu dodania BEGIN TRY/BEGIN CATCH w SQL 2k5. Przed blokami wyjątków w Transact-SQL naprawdę trudno było obsługiwać błędy, a niezrównoważone procedury były zbyt powszechne (procedury, które miały inny @@ TRANCOUNT przy wyjściu i wejściu).
Dzięki dodaniu języka Transact-SQL obsługa wyjątków jest znacznie łatwiejsza do napisania poprawnych procedur, które gwarantują prawidłowe równoważenie transakcji. Na przykład używam tego

szablon do obsługi wyjątków i transakcji zagnieżdżonych
http://rusanu.com/2009/06/11/e ... ions/
:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name; -- Do the actual work herelbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name; raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
end catch
end
go

To pozwala mi pisać niepodzielne procedury, które wycofują swoją własną pracę tylko w przypadku naprawialnych błędów.
Jednym z głównych problemów napotykanych przez procedury Transact-SQL jest

czystość danych
: czasami otrzymane parametry lub dane w tabelach są po prostu niepoprawne, co prowadzi do powielania błędów kluczowych, błędów ograniczeń odniesienia, błędów ograniczeń walidacji itp. W końcu to jest właśnie rola tych ograniczeń, jeśli te błędy czystości danych są niemożliwe i wszyscy zostaliby złapani przez logikę biznesową, wtedy wszystkie ograniczenia byłyby nieaktualne (dla efektu dodano dramatyczną przesadę). Jeśli XACT_ABORT jest włączona, wszystkie te błędy powodują utratę całej transakcji, w przeciwieństwie do możliwości kodowania bloków wyjątków, które wdzięcznie obsługują wyjątek. Typowym przykładem jest próba wykonania INSERT i powrotu do UPDATE w przypadku naruszenia PK.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Cytat

MSDN
http://msdn.microsoft.com/en-u ... .aspx
:

Jeśli SET XACT_ABORT jest ON, to jeśli instrukcja Transact-SQL spowoduje błąd w czasie wykonywania, cała transakcja zostanie zakończona i wycofana.
Gdy opcja SET XACT_ABORT jest wyłączona, w niektórych przypadkach tylko nieudana instrukcja Transact-SQL jest wycofywana, a transakcja kontynuuje przetwarzanie.

W praktyce oznacza to, że niektóre instrukcje mogą zawieść, pozostawiając transakcję „częściowo zakończoną” i wywołującemu może nie być żadnej wskazówki o tym niepowodzeniu.
Prosty przykład:
INSERT INTO t1 VALUES (1/0) 
INSERT INTO t2 VALUES (1/1)
SELECT 'Everything is fine'

Ten kod zostanie wykonany „pomyślnie” przy wyłączonym parametrze xact_abort i zakończy się niepowodzeniem z parametrem xact_abort do (polecenie „wstaw do T2” nie zostanie wykonane, a aplikacja kliencka zgłosi wyjątek).
Aby uzyskać bardziej elastyczne podejście, możesz sprawdzić @@ ERROR po każdej instrukcji (stara szkoła) lub użyć bloków TRY ... CATCH (MSSQL2005 +). Osobiście wolę ustawić XACT_ABORT, gdy nie ma powodu do jakiejś zaawansowanej obsługi błędów.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli chodzi o timeouty klientów i używanie XACT_ABORT do ich obsługi, to moim zdaniem istnieje co najmniej jeden bardzo dobry powód, aby mieć timeouty w interfejsach API klienta, takich jak SqlClient, a mianowicie w celu ochrony kodu aplikacji klienta przed zakleszczeniami występującymi w kodzie SQL Server. W takim przypadku kod klienta nie zawiera błędów, ale musi chronić się przed blokowaniem, czekając na zakończenie polecenia na serwerze. I odwrotnie, jeśli muszą istnieć limity czasu klienta, aby chronić kod klienta, XACT_ABORT ON musi chronić kod serwera przed przerwaniem przez klienta, jeśli wykonanie kodu serwera trwa dłużej, niż klient jest skłonny czekać.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jest używany w zarządzaniu transakcjami, aby zapewnić, że wszelkie błędy spowodują wycofanie transakcji.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się