DB 및 개발/SQL Server - Architecture

트랜잭션 3가지 상태!

Eastluck 2012. 3. 26. 12:06
XACT_STATE(Transact-SQL): http://msdn.microsoft.com/ko-kr/library/ms189797.aspx
SET XACT_ABORT(Transact-SQL): http://msdn.microsoft.com/ko-kr/library/ms188792.aspx



XACT_STATE :
 
1.비활성 트랜잭션 0
2.활성 상태이고 커밋 가능한 트랜잭션은 1
3.활성 상태이지만 커밋할 수 없는 상태 -1

-- 아래는 실험(반복 실행 >_<)

USE tempdb

go

 

IF OBJECT_ID('dbo.사원') IS NOT NULL

  DROP TABLE dbo.사원;

GO

CREATE TABLE dbo.사원

(

  사번   INT         NOT NULL,

  이름 VARCHAR(25) NOT NULL,

  직속상사   INT         NULL,

  CONSTRAINT PK_사원 PRIMARY KEY(사번));

 

BEGIN TRY

 

  BEGIN TRAN

    INSERT INTO dbo.사원(사번, 이름, 직속상사)

      VALUES(3, 'Emp3', 1);

    /* 다른작업*/

  COMMIT TRAN

 

  PRINT 'Code completed successfully.';

 

END TRY

BEGIN CATCH

 

  PRINT 'Error: ' + CAST(ERROR_NUMBER() AS VARCHAR(10)) + ' found.';

 

  IF (XACT_STATE()) = -1

  BEGIN

    PRINT 'Transaction is open but uncommittable.';

    /* 데이터조사*/

    ROLLBACK TRAN; -- can only ROLLBACK

    /* 오류처리*/

  END

  ELSE IF (XACT_STATE()) = 1

  BEGIN

    PRINT 'Transaction is open and committable.';

    /* 오류처리*/

    COMMIT TRAN; -- or ROLLBACK

  END

  ELSE

  BEGIN

    PRINT 'No open transaction.';

    /* 오류처리*/

  END

 

END CATCH

 

 

--(1개행이영향을받음)

--Code completed successfully.

 

--Error: 2627 found.

--Transaction is open and committable.

--오류처리

 

-- SET XACT_ABORT ON 세션옵션을준다

--Error: 2627 found.

--Transaction is open but uncommittable.
--롤백만할수있음 
 



-1은 어떤 경우에 나오는가? 


--//OFF 로 설정된 경우에는.. 1의 데이터가 들어갑니다..

SET XACT_ABORT OFF;

BEGIN TRAN

INSERT INTO dbo.사원(사번, 이름, 직속상사) VALUES(1, 'Emp3', 1);

INSERT INTO dbo.사원(사번, 이름, 직속상사) VALUES(3, 'Emp3', 1);

COMMIT


--//하지만.. ON으로 설정이 되어있으면.. 즉시 롤백이 되버립니다.


그런데.. BEGIN TRY 구문을 쓰게 되면..

ROLLBACK이 바로 수행되는게 아니라..

CATCH문에.. ROLLBACK을 반드시 해주어야 합니다.


즉... 중복된 행이 INSERT가 되었지만.. 들어갈 수 없기 때문에 ROLLBACK이 되어야만 하는 것이죠~!


SET XACT_ABORT ON;

으로 해두고..

소스의 내용중 아래 내용 중 ROLLBACK 구문을 주석처리 하게되면..


PRINT 'Transaction is open but uncommittable.';

    /* 데이터조사*/

    --ROLLBACK TRAN; -- can only ROLLBACK

    /* 오류처리*/


아래와 같은 에러가 나게 됩니다~

Transaction is open but uncommittable.

Msg 3998, Level 16, State 1, Line 1

커밋할 수 없는 트랜잭션이 일괄 처리 맨 끝에서 검색되었습니다. 트랜잭션이 롤백됩니다.


참고가 되셨으면 좋겠네요~~


PRINT 문도.. 아래 처럼 수정하면.. 현재 남아있는 TRANCOUNT도 볼 수 있겠지요~

PRINT 'Error: ' + CAST(ERROR_NUMBER() AS VARCHAR(10)) + ' found. TranCount: '+ CAST(@@TRANCOUNT AS VARCHAR(10));