본문 바로가기

프로그램 경험/Database

[SqlServer] @@IDENTITY 의문점들

후배와 ID열에 관련 대화를 하다가 SqlServer에 ID열이 자동 저장된 후 그 ID 데이터를 알수 있는 전역변수에 대해 생각났다. 

 @@IDENTITY --이것이다! 

이 변수는 자동증가형 ID 열에 마지막으로 삽입된 값을 보여준다. 
이때 궁금한 점이 2개가 생겼다. 

첫번째는 트랜젝션을 잡아두고 INSERT 할때 그 트랜젝션이 끝나지 않았을때 
다른 트랜젝션에서 INSERT를 시도 하면 @@IDENTITY값은 무엇일까? 

두번째는 INSERT를 다중으로 할때 중간에 INSERT 한 IDENTITY는 어떻게 알수 있을까?

우선 테이블을 하나 생성하고 테스트를 시작했다.

CREATE TABLE [dbo].[TestIdentity](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[data] [varchar](50) NULL
) ON [PRIMARY]

두번째 문제가 비교적 쉬워보여 먼저 테스트 해봤다.
  
INSERT INTO TestIdentity VALUES('a1')
INSERT INTO TestIdentity VALUES('a2')
PRINT @@IDENTITY

결과는 2가 출력된다. 중간에 @@IDENTITY 껴서 출력해 보면

INSERT INTO TestIdentity VALUES('a3')
PRINT @@IDENTITY

INSERT INTO TestIdentity VALUES('a4')
PRINT @@IDENTITY

결과는 3, 4가 출력된다. 
그저 @@IDENTITY 는 마지막으로 저장된 ID값을 반환하는 걸로 보인다.
중간 INSERT의 ID를 유지 하려면 변수를 선언해서 담아두는 방법을 사용해야 할것 같다. 

첫번째 문제로 돌아 와서, 테스트를 위해 쿼리창을 두개 열고 첫번째 쿼리창은 아래와 같이 준비 했다.

BEGIN TRAN

DECLARE @i INT
SET @i = 1

INSERT INTO TestIdentity VALUES('a5')
PRINT @@IDENTITY

WHILE(@i < 10000000) -- 수초간 딜레이 된다.
BEGIN
	SET @i = @i + 1
END

ROLLBACK TRAN

그리고 다른창에는 아래와 같이 준비했다.
  
INSERT INTO TestIdentity VALUES('a6')
PRINT @@IDENTITY

첫번째 창에서 쿼리를 실행시키고 트랜젝션에 들어가 있는 동안에 두번째 창의 쿼리를 재빠르게 실행 시키는 방법으로 테스트 했다. 

결과는 첫번째 창은 5를 출력하였으나 롤백되어 테이블엔 남아 있지 않았고
두번째 창은 6을 출력하고 테이블에 입력되었다. 

결국 트랜젝션이 걸려 있어도 그 트랜젝션이 끝나기를 기다려 ID를 증가 하는 것이 아니란 것이었다.