Programming/MSSQL

MSSQL GO문 트랜잭션

장형이 2023. 4. 27. 08:01

개요

MSSQL에서 스키마를 다량으로 추가/수정하는 쿼리를 테스트하려고 [BEGIN TRAN]-[ROLLBACK TRAN]을 걸고 테스트하는 도중, [ROLLBACK TRAN]이 씹히고 스키마가 모조리 변경되는 대참사가 발생한 이슈가 있어서 기록 및 제대로 이해하려는 목적으로 포스팅을 한다.

 

GO를 사용하지 않는 트랜잭션

BEGIN TRAN

SELECT @@TRANCOUNT -- : 1
CREATE TABLE [dbo].[TEST1] -- 추후에 롤백됨.
(
  [id] INT
);

CREATE TABLE [dbo].[TEST1] -- 중복 생성으로 인한 에러가 발생하고, 트랜잭션이 롤백된 채로 이후 모든 명령어가 무시된다.
(
  [id] INT
);
SELECT @@TRANCOUNT -- : 출력되지 않는다.

CREATE TABLE [dbo].[TEST2] -- 생성되지 않는다.
(
  [id] INT
);
SELECT @@TRANCOUNT -- : 출력되지 않는다.

ROLLBACK TRAN

GO를 사용하지 않았다면, CREATE TABLE 실패 이후에 트랜잭션이 롤백되어 아무일도 일어나지 않는다.

(CREATE문은 실패하면 XACT_ABORT 설정과 상관 없이 전체 트랜잭션을 롤백한다. 왜 그런지는 못찾겠다 꾀꼬리....)

 

GO를 사용한 트랜잭션

BEGIN TRAN

SELECT 1, @@TRANCOUNT -- : 1
CREATE TABLE [dbo].[TEST1] -- 추후에 롤백됨.
(
  [id] INT
);
GO

CREATE TABLE [dbo].[TEST1] -- 중복 생성으로 인한 에러 발생. (이후, 트랜잭션이 롤백된다.)
(
  [id] INT
);
SELECT 2, @@TRANCOUNT -- : 출력되지 않는다.
GO

CREATE TABLE [dbo].[TEST2] -- 생성 성공
(
  [id] INT
);
SELECT 3, @@TRANCOUNT -- : 0
GO

ROLLBACK TRAN -- Rollback 할 Tran이 없으므로 에러 발생.

GO문은 만나기 전에 적혀있던 명령어들을 마치 따로 실행시키듯이 분리시키는 명령이다.

그래서 위 쿼리는 아래와 같이 따로 쿼리를 치는 것과 다를바 없이 해석되게 된다.

 

결론

GO는 아주 편리한 도구이지만 남용하면 대참사를 일으 킬 수 있으니 주의해서 써야 되겠다.

트랜잭션을 걸었다고 생각 없이 쿼리를 막 치지 말자.. 역시 대참사가 발생할 수 있다.