Data Modeling Evangelist Kaien Kim's Blog
[SQLServer] TRY..CATCH를 이용한 중첩 트랜잭션 예외처리. 본문
TRY..CATCH를 이용한 중첩 트랜잭션 예외처리. |
개요.
TRY .. CATCH 구문 내에서의 트랙잭션 처리에 대해 어떻게 구현되는지 알아보는 것과 트랜잭션으로 처리하는 프로시저 내에서
다시 트랜잭션으로 처리하는 프로시저를 호출 시 제대로 작동하는지 확인하는 것이 이 문서의 목적입니다.
테스트 샘플.
테스트 샘플은 분모를 파라미터로 받아서 0을 제외한 값은 에러가 나지 않고 0인 값은 에러가 나는 예제입니다.
1. 테스트 테이블 생성
CREATE TABLE TryTest
(
id1 int,
id2 int
)
2. 부모 프로시저 작성.
CREATE PROCEDURE ParentTest
(
@bunmo int
)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN ParentTest1
INSERT INTO TryTest VALUES(2,1)
EXEC ChildTest @bunmo
PRINT('ParentTest')
INSERT INTO TryTest VALUES(2,2)
COMMIT TRAN ParentTest1
END TRY
BEGIN CATCH
ROLLBACK TRAN ParentTest1
PRINT('Parent ERROR')
END CATCH
SET NOCOUNT OFF;
END
3. 자식 프로시저 작성.
CREATE PROCEDURE ChildTest (
@bunmo int
)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN ChildTest1
INSERT INTO TryTest VALUES(1,1)
PRINT(1/@bunmo)
INSERT INTO TryTest VALUES(1,2)
COMMIT TRAN ChildTest1
END TRY
BEGIN CATCH
ROLLBACK TRAN ChildTest1
PRINT('Child ERROR')
END CATCH
SET NOCOUNT OFF;
END
4. 실행.
4.1. 에러 발생 시
EXEC ParentTest 0
실행 결과 : Parent ERROR
데이터 결과 : 데이터 쌓이지 않음.
흐름.
ParentTest 프로시저에 2,1로 데이터를 등록 후 ChildTest 프로시저를 실행합니다.
ChildTest 내에서 1,1을 인서트 후 0으로 나누려 했기 때문에 CATCH 구문으로 이동하여 롤백합니다.
'Child ERROR' 를 출력하지 않는 이유는 ROLLBACK TRAN ChildTest1 시점에 이 프로시저를 벗어나기 때문입니다.
다시 ParentTest으로 넘어온 후 ‘ParentTest‘ 를 출력하지 않고 부모에서 ROLLBACK이 되었기 때문에
바로 CATCH 구문으로 이동합니다.
롤백 처리한 후 'Parent ERROR' 를 출력합니다.
결국 Parent, Child 모두 롤백되므로 인서트된 데이터들은 없습니다.
4.2. 정상 실행 시
EXEC ParentTest 1
실행 결과 :
1
ParentTest
데이터 결과 : 4건 등록됨.
2 1
1 1
1 2
2 2
흐름.
ParentTest 프로시저에 2,1로 데이터를 등록 후 ChildTest 프로시저를 실행합니다.
ChildTest 내에서 1,1을 인서트 후 1로 나누려 했기 때문에 CATCH 구문으로 이동하지 않고 1,2를 인서트 합니다.
트랜잭션을 COMMIT 시킨 후 Parent로 돌아와서 ‘ParentTest’ 를 출력 후 2,2를 인서트하고 COMMIT 시킵니다.
5. 결론
TRY..CATCH를 이용하여 중첩 프로시저 호출로 인한 트랜잭션 처리는 데이터 무결성을 보장합니다.
출처 : http://www.mobilepro.pe.kr/trackback_post_122.aspx
'DATA > SQLServer' 카테고리의 다른 글
[SQLServer] 특정문자가 포함된 StoredProcedure 찾기 (0) | 2010.09.29 |
---|---|
[SQLServer] 동적 쿼리의 해결사 sp_executesql vs. exec (0) | 2010.09.01 |
[SQLServer] 데이터의 길이 가져오기 (0) | 2009.12.21 |
[SQLServer] Unix_timestamp 형식의 데이터를 일반시간으로 변환 (0) | 2009.08.27 |
[SQLServer] SQLServer2005설치 후 확인하기 (0) | 2009.07.14 |