SQL Server 트랜잭션 관리 및 TRY...CATCH 오류 처리 가이드

T-SQL 스크립트나 저장 프로시저 개발 시 런타임 오류는 시스템 안정성을 해칠 수 있는 주요 요인입니다. 클라이언트 애플리케이션 단에서 예외를 처리하는 것도 가능하지만, 데이터 무결성을 보장하기 위해서는 데이터베이스 서버 단에서 직접 오류를 감지하고 트랜잭션을 제어하는 것이 필수적입니다.

트랜잭션 없이 오류 감지하기

BEGIN TRY 블록 내에서 오류 발생 시 제어권이 BEGIN CATCH 블록으로 이동합니다. 이때 자동 롤백은 발생하지 않으므로 명시적인 처리가 필요합니다. 다음 예시는 임시 테이블을 사용하여 데이터 타입 불일치 오류를 감지하는 과정입니다.

DECLARE #ValidationTemp TABLE (NumValue INT);

BEGIN TRY  
    INSERT INTO #ValidationTemp VALUES (10);     
    INSERT INTO #ValidationTemp VALUES ('TextError');  
END TRY  
BEGIN CATCH  
    PRINT 'Err No: ' + CAST(ERROR_NUMBER() AS VARCHAR(10));
    PRINT 'Err Msg: ' + ERROR_MESSAGE();
    PRINT 'Err Sev: ' + CAST(ERROR_SEVERITY() AS VARCHAR(10));
    PRINT 'Err State: ' + CAST(ERROR_STATE() AS VARCHAR(10));
    PRINT 'Err Line: ' + CAST(ERROR_LINE() AS VARCHAR(10));
    PRINT 'Err Proc: ' + COALESCE(ERROR_PROCEDURE(), 'None');
END CATCH;

위 코드에서 CATCH 블록은 오류 정보를 출력하지만, 이미 성공한 첫 번째 INSERT 문은 취소되지 않습니다. 데이터의 일관성을 유지하려면 트랜잭션과 결합해야 합니다.

트랜잭션과 결합한 오류 처리

원자성을 보장하기 위해 BEGIN TRANSACTION 을 사용합니다. 오류 발생 시 ROLLBACK 을 수행하여 변경 사항을 모두 취소합니다. 또한 XACT_STATE() 를 확인하여 트랜잭션 상태를 판단하는 것이 좋습니다.

IF OBJECT_ID('dbo.WorkLog', 'U') IS NOT NULL 
    DROP TABLE dbo.WorkLog;

CREATE TABLE dbo.WorkLog (Seq INT);

BEGIN TRANSACTION;
BEGIN TRY  
    INSERT INTO dbo.WorkLog VALUES (100);     
    INSERT INTO dbo.WorkLog VALUES ('InvalidData');  
    COMMIT TRANSACTION;
END TRY  
BEGIN CATCH  
    IF (XACT_STATE()) <> 0
        ROLLBACK TRANSACTION;

    PRINT 'Err No: ' + CAST(ERROR_NUMBER() AS VARCHAR(10));
    PRINT 'Err Msg: ' + ERROR_MESSAGE();
    PRINT 'Err Sev: ' + CAST(ERROR_SEVERITY() AS VARCHAR(10));
    PRINT 'Err State: ' + CAST(ERROR_STATE() AS VARCHAR(10));
    PRINT 'Err Line: ' + CAST(ERROR_LINE() AS VARCHAR(10));
    PRINT 'Err Proc: ' + COALESCE(ERROR_PROCEDURE(), 'None');
END CATCH;

실행 후 SELECT * FROM dbo.WorkLog 를 조회하면 트랜잭션이 롤백되었으므로 테이블에 데이터가 존재하지 않음을 확인할 수 있습니다.

태그: SQLServer T-SQL transaction ErrorHandling DatabaseDev

8월 23일 08:02에 게시됨