Database/MS SQL

TRY CATCH는 과연 만고땡인가?

catchv 2013. 4. 23. 15:27
반응형

버전 : SQL 2005, SQL 2008, SQL 2008 R2, SQL 2012

MS SQL Server 2005 이상부터 C++에나 있던 TRY CATCH 구문이
도입되어서 굉장히 편하게 에러가 발생되는 부분을 찾고 처리하기 쉽게 되었다.
BEGIN TRY
    SELECT 1 / 0
END TRY
BEGIN
CATCH
SELECT
        ERROR_NUMBER()    AS ErrorNumber
    ,    ERROR_SEVERITY()    AS ErrorSeverity
    ,    ERROR_STATE()        AS ErrorState
    ,    ERROR_PROCEDURE()    AS ErrorProcedure
    ,    ERROR_LINE()        AS ErrorLine
    ,    ERROR_MESSAGE()    AS ErrorMessage;
END CATCH


그러나 TRY CATCH 가 모든 에러를 체크하는 것은 아니다.

우선 아래의 상황을 보자

1번 세션

BEGIN TRY
    BEGIN TRAN
        -- 무엇인가 작업???
        -- INSERT INTO Test1234 VALUES(1)
        -- 10 초 대기
        WAITFOR DELAY '00:00:10'
    COMMIT
END TRY
BEGIN CATCH
    ROLLBACK

SELECT
        ERROR_NUMBER()    AS ErrorNumber
    ,    ERROR_SEVERITY()    AS ErrorSeverity
    ,    ERROR_STATE()        AS ErrorState
    ,    ERROR_PROCEDURE()    AS ErrorProcedure
    ,    ERROR_LINE()        AS ErrorLine
    ,    ERROR_MESSAGE()    AS ErrorMessage;
END CATCH


실행 후에 10초가 넘기 전에 중지버튼으로 쿼리를 중지해 보자

그리고

SELECT    @@TRANCOUNT AS TRAN_COUNT

실행하면 Transaction이 1개 남아 있는 것을 확인 할 수 있다.

 

이제 테이블을 하나 만들고 다음과 같은 상황을 만들자

 

CREATE TABLE Test1234

(

    A INT

)

GO

 

아래 부분의 주석을 제거 하고

INSERT INTO Test1234 VALUES(1)

 

"새 쿼리(N)" 버튼을 눌러서 다른 세션을 만들고 다음과 같이 입력을 해 놓자

2번 세션

SELECT * FROM Test1234

 

자 이제 테스트를 해보자

 

1번 세션에서 쿼리 옵션의 TIMEOUT 값을 변경하자

 

1번 세션을 실행하고 바로 2번 세션을 실행하고 1번 세션에서 5초를 기다려 보자.
(실행 제한 시간으로 5초 후에 자동 중단된다.)
아까 TRANCOUNT를 봐서 예상 했겠지만 2번 세션은 LOCK이 걸려 블로킹 상태로 대기 중이다.

 

이런 현상이 외부 PDA같은 것을 사용하는 경우 빈번하게 발생 할 수 있다.

해결 방법은 다음과 같다

1번 세션

SET XACT_ABORT ON;
BEGIN TRY
    BEGIN TRAN
        INSERT INTO Test1234 VALUES(1)
        -- 10 초 대기
        WAITFOR
DELAY '00:00:10'
    COMMIT
END
TRY
BEGIN
CATCH
    ROLLBACK

    SELECT
            ERROR_NUMBER()        AS ErrorNumber
        ,    ERROR_SEVERITY()    AS ErrorSeverity
        ,    ERROR_STATE()        AS ErrorState
        ,    ERROR_PROCEDURE()    AS ErrorProcedure
        ,    ERROR_LINE()        AS ErrorLine
        ,    ERROR_MESSAGE()        AS ErrorMessage;
END CATCH
SET
XACT_ABORT OFF;

 

XACT_ABORT 은 보통 링크드 서버나 이기종간의 쿼리를 작성할 때 많이 사용했었는데

같은 원리로 세션의 문제가 생겼을때도 사용할 수 있다.

 

 

반응형

'Database > MS SQL' 카테고리의 다른 글

Replication(복제) 삭제 에러시 ( error 18482 )  (0) 2013.08.09
SQL Server Error Log 관리  (0) 2013.04.25
MS SQL 2008 이상 BACKUP LOG TRUNCATE_ONLY , NO_LOG  (0) 2013.04.23
Fill Factor  (0) 2013.04.16
암호화된 Procedure 보는 방법  (2) 2013.04.13