2012-03-06 3 views
-1

여기가 catch 블록과 인쇄 트랜잭션을 롤백하고 또한 SELECT 문 결과 (등 오류 메시지)를 표시 입력,SQL 트랜잭션이 롤백되지 않는 이유는 무엇입니까? 스크립트가 실패하면

USE databaseName 

BEGIN TRY 
    DECLARE @count INT 
    DECLARE @ErrorMsg VARCHAR(MAX) 

    SET @count=(SELECT COUNT(*) 
       FROM xxxtable 
       WHERE xxxcolumn = 'xxx') 

    IF(@count = 0) --This means that the script has not been run yet  
     BEGIN 
      BEGIN TRANSACTION 

      --do work in here 
      COMMIT TRANSACTION 
     END 
    ELSE 
     BEGIN 
      SELECT 'This script has already been run before. Cannot run it again.' 
     END 
END TRY 

BEGIN CATCH 
    IF(Xact_state() <> 0) 
     BEGIN 
      ROLLBACK TRAN 

      PRINT('ROLLED BACK TRANSACTION') 

      SELECT Error_number() AS error_number, 
       Error_line() AS error_line, 
       Error_message() AS error_message 
     END 
END CATCH 

밖으로 스트라이프 불필요한 부분과 스크립트입니다.

그러나 데이터베이스를 체크인 할 때 오류 지점까지의 데이터가 커밋됩니다. 여기서 내가 뭘 잘못하고 있니?

업데이트 : 데이터를 롤백하면 사용 가능한 최신 ID 값이 변경됩니다. (삽입 및 롤백하면 사용 가능한 가장 높은 ID는 10이고 사용 가능한 가장 높은 ID는 11이고 더 이상은 10이 아님). 따라서 롤백은 트랜잭션 이전의 상태로 데이터베이스를 리턴하지 않습니다. 이것이 문제의 원인이었습니다.

+0

스트립 된 코드에서 커밋이 숨겨져있을 가능성이 있습니까? 명령문의 실행을 모니터하여 각 데이터베이스에 변경 사항이 발생할 때를 확인하려고 했습니까? – Gambrinus

+0

스트라이프 코드에는 커밋이 없습니다. 위의 스크립트에서 볼 수 있듯이 마지막에 커밋이 하나만 있습니다. ( – developer747

+0

스크립트가 실패 할 때 어떤 오류 메시지가 나타 납니까? – HLGEM

답변

1

업데이트 : IDENTITY 값을 기준으로하면 이것은 예상되는 동작입니다. 롤백은 IDENTITY 값을 다시 설정하지 않으므로 ID 값에 갭을 생성합니다.

아마도 "실패 시점까지의 데이터가 커밋 될 때까지"라고 말하면 - 이 아닌 일 것입니다. 트랜잭션에서 업데이트/삽입 한 모든 데이터는 롤백 이후에도 계속 남아 있습니다.

+0

정확합니다. – developer747

관련 문제