programing tip

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

itbloger 2020. 5. 30. 22:18
반응형

저장 프로 시저에서 "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'가 실행되지 않으며 클라이언트 응용 프로그램에서 예외가 발생 함).

As a more flexible approach, you could check @@ERROR after each statement (old school), or use TRY...CATCH blocks (MSSQL2005+). Personally I prefer to set XACT_ABORT ON whenever there is no reason for some advanced error handling.


Regarding client timeouts and the use of XACT_ABORT to handle them, in my opinion there is at least one very good reason to have timeouts in client APIs like SqlClient, and that is to guard the client application code from deadlocks occurring in SQL server code. In this case the client code has no fault, but has to protect it self from blocking forever waiting for the command to complete on the server. So conversely, if client timeouts have to exist to protect client code, so does XACT_ABORT ON has to protect server code from client aborts, in case the server code takes longer to execute than the client is willing to wait for.


It is used in transaction management to ensure that any errors result in the transaction being rolled back.

참고URL : https://stackoverflow.com/questions/1150032/what-is-the-benefit-of-using-set-xact-abort-on-in-a-stored-procedure

반응형