트랜잭션 3가지 상태!
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)); |