2010년 1월 6일 수요일

Transaction

출처: DBGuide


Question

CREATE  PROC [dbo].[usp111]  @U  int,@C tinyint,@D tinyint
 BEGIN TRAN
 DECLARE @ReturnStatus INT
 INSERT INTO [dbo].[test] ([U], [C], [d])
 SELECT  @U, @C, @d

 IF @@ERROR <> 0 OR @@ROWCOUNT <> 1 GOTO QuitWithRollback
     
 COMMIT TRAN
 GOTO EndSave

QuitWithRollback:
    IF (@@TRANCOUNT > 0)
 BEGIN
 ROLLBACK TRANSACTION
 SELECT 0
 RETURN
 END
EndSave:
 SELECT 1

 

 

 

 

CREATE  PROC [dbo].[usp333]  @U  int,@C tinyint,@D tinyint
AS
 SET NOCOUNT ON
 
 DECLARE @Flag TINYINT
 INSERT INTO [dbo].[test] ([U], [C], [d])
 VALUES(@U, @C, @d)

 IF @@ERROR <> 0 OR @@ROWCOUNT <> 1
 BEGIN
  SELECT @Flag
 END

 ELSE
 BEGIN
  SELECT @Flag
 END
GO

 

굳이 트랜잭션을 걸 필요는 없는 상태이긴 한데 트랜잭션을 해 놓은 거랑 안 해놓은것..

그리고 select 로 하는 건 안 좋고 return 으로 해야 성능이 좋다고 하는게 이게 맞는 이야기 인가요?



Answer

MSSQL 에서는 기본적으로 암시적 트랜잭션을 사용합니다.

 

명시적 트랜잭션은 하나이상의 문장에 대한 일관성을 위해서 사용합니다.

그렇기 때문에, 위의 예제처럼 하나의 INSERT 문인 경우에는 굳이 BEGIN TRAN을 사용하지 않아도 크게 문제되지 않습니다.

 

대신 아래와 같이 여러개의 문장에 대해 트랜잭션 일관성을 유지해야 한다면 반드시 명시적 트랜잭션을 사용해야 합니다.

 

BEGIN TRAN

 

INSERT ... SELECT 1

IF @@ERROR <> 0

BEGIN

    ROLLBACK TRAN
    RETURN

END

 

INSERT ... SEECLT 2

IF @@ERROR <> 0

BEGIN

    ROLLBACK TRAN
    RETURN

END

 

COMMIT TRAN

 

 

결과를 반환하는 것이 아니라 단순한 플래그 값만을 가져오는 것이라면 RETURN을 쓸 수 있지만,

필요한 결과를 여러 개의 값으로 반환해야 한다면 SELECT를 사용해야 합니다.

(SELECT를 사용한다고 해서 크게 성능 문제가 발생하지는 않습니다. 물론, 불필요하다면 SELECT를 사용하지 않아야 하겠지요)

 

감사합니다.

 

SQL Server MVP

성대중

0 개의 댓글:

댓글 쓰기