Jaka jest korzyść z używania SET XACT_ABORT ON
w procedurze składowanej?
sql
sql-server
odiseh
źródło
źródło
Odpowiedzi:
SET XACT_ABORT ON
instruuje SQL Server, aby wycofał całą transakcję i przerwał partię, gdy 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 SQL Server (co nie jest objęteXACT_ABORT OFF
ustawieniem domyślnym ).Ponieważ przekroczenie limitu czasu zapytania pozostawi transakcję otwartą,
SET XACT_ABORT ON
jest zalecane we wszystkich procedurach składowanych z jawnymi transakcjami (chyba że masz konkretny powód, aby zrobić inaczej), ponieważ konsekwencje wykonywania pracy przez aplikację na połączeniu z otwartą transakcją są katastrofalne.Na blogu Dana Guzmana znajduje się naprawdę świetny przegląd ,
źródło
BEGIN TRY
-BEGIN CATCH
iROLLBACK
zBEGIN CATCH
blokiem w Sql?BEGIN TRY
-BEGIN CATCH
nie przechwytuje takich rzeczy, jak przekroczenie limitu czasu występującego w aplikacji klienckiej, a niektóre błędy SQL są również nie do wykrycia, pozostawiając otwartą transakcję, której się nie spodziewałeś.Moim zdaniem SET XACT_ABORT ON stał się przestarzały przez dodanie BEGIN TRY / BEGIN CATCH w SQL 2k5. Przed blokami wyjątków w Transact-SQL obsługa błędów była naprawdę trudna, a niezrównoważone procedury były zbyt powszechne (procedury, które miały inny @@ TRANCOUNT na wyjściu w porównaniu z wejściem).
Dzięki dodaniu obsługi wyjątków języka Transact-SQL pisanie poprawnych procedur, które gwarantują prawidłowe zbilansowanie transakcji, jest znacznie łatwiejsze. Na przykład używam tego szablonu do obsługi wyjątków i transakcji zagnieżdżonych :
Pozwala mi na pisanie atomowych procedur, które wycofują tylko swoją własną pracę w przypadku naprawialnych błędów.
Jednym z głównych problemów, z jakimi borykają się procedury Transact-SQL, jest czystość danych : czasami otrzymane parametry lub dane w tabelach są po prostu błędne, co skutkuje zduplikowanymi błędami klucza, błędami ograniczeń referencyjnych, błędami ograniczeń sprawdzania i tak dalej. W końcu to właśnie rola tych ograniczeń, jeśli te błędy czystości danych byłyby niemożliwe i wszystkie zostałyby przechwycone przez logikę biznesową, wszystkie ograniczenia byłyby przestarzałe (dramatyczna przesada dodana dla efektu). Jeśli XACT_ABORT jest ON, wszystkie te błędy powodują utratę całej transakcji, w przeciwieństwie do możliwości kodowania bloków wyjątków, które z wdziękiem obsługują wyjątek. Typowym przykładem jest próba wykonania INSERT i powrót do UPDATE w przypadku naruszenia PK.
źródło
Cytując MSDN :
W praktyce oznacza to, że niektóre instrukcje mogą się nie powieść, pozostawiając transakcję „częściowo zakończoną” i wywołującemu może nie być żadnego znaku tego niepowodzenia.
Prosty przykład:
Ten kod zostałby wykonany „pomyślnie” przy wyłączonym XACT_ABORT i zakończyłby się błędem przy włączonym XACT_ABORT („INSERT INTO t2” nie zostanie wykonany, a aplikacja kliencka zgłosi wyjątek).
Bardziej elastycznym podejściem jest sprawdzenie @@ ERROR po każdej instrukcji (stara szkoła) lub użycie bloków TRY ... CATCH (MSSQL2005 +). Osobiście wolę ustawić XACT_ABORT ON, gdy nie ma powodu do zaawansowanej obsługi błędów.
źródło
Jeśli chodzi o timeouty klientów i użycie XACT_ABORT do ich obsługi, moim zdaniem istnieje co najmniej jeden bardzo dobry powód, aby mieć limity czasu w API klienta, takie jak SqlClient, a mianowicie chronić kod aplikacji klienta przed zakleszczeniami występującymi w kodzie serwera SQL. W tym przypadku kod klienta nie ma błędu, ale musi chronić go przed zablokowaniem na zawsze, 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 przerwaniami klienta, na wypadek gdyby kod serwera trwał dłużej, niż klient jest skłonny czekać.
źródło
Jest używany w zarządzaniu transakcjami, aby zapewnić, że wszelkie błędy spowodują wycofanie transakcji.
źródło