SET XACT_ABORT ON
저장 프로 시저에서 사용하면 어떤 이점이 있습니까?
답변
SET XACT_ABORT ON
런타임 오류가 발생할 때 전체 트랜잭션을 롤백하고 배치를 중단하도록 SQL Server에 지시합니다. SQL Server 자체가 아닌 클라이언트 응용 프로그램에서 명령 시간 초과가 발생하는 경우 (기본 XACT_ABORT OFF
설정 에서는 다루지 않음 )를 설명합니다.
쿼리 시간이 초과되면 트랜잭션이 열린 상태로 유지되므로 SET XACT_ABORT ON
명시적인 트랜잭션이있는 모든 저장 프로 시저에서 (다른 이유가없는 한) 열린 트랜잭션과의 연결에서 작업을 수행하는 응용 프로그램의 결과가 비참하기 때문에 권장됩니다.
Dan Guzman의 블로그 에는 정말 훌륭한 개요가 있습니다 .
답변
내 생각에 SET XACT_ABORT ON은 SQL 2k5에서 BEGIN TRY / BEGIN CATCH를 추가하여 폐기되었습니다. Transact-SQL의 예외 블록 이전에는 오류를 처리하기가 실제로 어려웠으며 균형이 맞지 않은 프로 시저가 너무 흔했습니다 (항목과 종료시 @@ TRANCOUNT가 다른 프로 시저).
Transact-SQL 예외 처리를 추가하면 트랜잭션의 균형을 올바르게 유지할 수있는 올바른 프로 시저를 훨씬 쉽게 작성할 수 있습니다. 예를 들어 예외 처리 및 중첩 트랜잭션 에이 템플릿을 사용 합니다 .
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 here
lbexit:
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
복구 가능한 오류가 발생했을 때 자체 작업 만 롤백하는 원자 적 절차를 작성할 수 있습니다.
Transact-SQL 프로 시저가 직면 한 주요 문제 중 하나는 데이터 순도입니다 . 때때로 수신 된 매개 변수 또는 테이블의 데이터가 잘못되어 중복 키 오류, 참조 제한 오류, 제한 오류 확인 등이 발생합니다. 결국, 이것이 바로 이러한 제약의 역할입니다. 이러한 데이터 순도 오류가 불가능하고 비즈니스 논리에 의해 모두 잡히면 제약이 모두 더 이상 사용되지 않습니다 (효과를 위해 과장된 과장). XACT_ABORT가 ON이면 예외를 정상적으로 처리하는 예외 블록을 코딩 할 수있는 것과는 달리 이러한 모든 오류로 인해 전체 트랜잭션이 손실됩니다. 일반적인 예는 INSERT를 시도하고 PK 위반시 UPDATE로 되 돌리는 것입니다.
답변
인용 MSDN :
SET XACT_ABORT가 ON이면 Transact-SQL 문에서 런타임 오류가 발생하면 전체 트랜잭션이 종료되고 롤백됩니다. SET XACT_ABORT가 OFF이면 경우에 따라 오류를 발생시킨 Transact-SQL 문만 롤백되고 트랜잭션 처리가 계속됩니다.
실제로 이것은 일부 명령문이 실패하여 트랜잭션이 ‘부분적으로 완료’된 상태로 남아있을 수 있으며 호출자에게이 실패의 징후가 없을 수 있음을 의미합니다.
간단한 예 :
INSERT INTO t1 VALUES (1/0)
INSERT INTO t2 VALUES (1/1)
SELECT 'Everything is fine'
이 코드는 XACT_ABORT OFF로 ‘성공적으로’실행되고 XACT_ABORT ON으로 오류로 종료됩니다 ( ‘INSERT INTO t2’가 실행되지 않으며 클라이언트 응용 프로그램에서 예외가 발생 함).
보다 유연한 접근 방식으로 각 문 (구식 학교) 후에 @@ ERROR를 확인하거나 TRY … CATCH 블록 (MSSQL2005 +)을 사용할 수 있습니다. 개인적으로 고급 오류 처리의 이유가 없을 때마다 XACT_ABORT를 ON으로 설정하는 것을 선호합니다.
답변
클라이언트 시간 초과 및 XACT_ABORT를 사용하여 처리하는 것과 관련하여 SqlClient와 같은 클라이언트 API에서 시간 초과가 발생하고 클라이언트 응용 프로그램 코드가 SQL Server 코드에서 발생하는 교착 상태로부터 보호 해야하는 이유는 적어도 하나 이상이라고 생각합니다. 이 경우 클라이언트 코드에는 결함이 없지만 서버에서 명령이 완료 될 때까지 기다리지 않도록 자체적으로 차단해야합니다. 반대로, 클라이언트 코드를 보호하기 위해 클라이언트 제한 시간이 존재해야하는 경우, XACT_ABORT ON은 클라이언트가 대기하는 것보다 서버 코드 실행 시간이 길어질 경우를 대비하여 클라이언트 중단으로부터 서버 코드를 보호해야합니다.
답변
트랜잭션 관리에서 오류가 발생하여 트랜잭션이 롤백되도록합니다.