[sql] 저장 프로 시저에서 “SET XACT_ABORT ON”을 사용하면 어떤 이점이 있습니까?

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은 클라이언트가 대기하는 것보다 서버 코드 실행 시간이 길어질 경우를 대비하여 클라이언트 중단으로부터 서버 코드를 보호해야합니다.


답변

트랜잭션 관리에서 오류가 발생하여 트랜잭션이 롤백되도록합니다.


답변