-
트랜잭션 3가지 상태!SQL Server/Architecture 2012. 3. 26. 12:06XACT_STATE(Transact-SQL): http://msdn.microsoft.com/ko-kr/library/ms189797.aspxSET XACT_ABORT(Transact-SQL): http://msdn.microsoft.com/ko-kr/library/ms188792.aspx
XACT_STATE :1.비활성 트랜잭션 02.활성 상태이고 커밋 가능한 트랜잭션은 13.활성 상태이지만 커밋할 수 없는 상태 -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));