为什么SQL事务没有回滚?

时间:2012-03-06 14:47:21

标签: sql-server-2008 transactions

这是带有不必要部分的脚本

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 

当脚本失败时,它进入catch块并打印ROLLED BACK TRANSACTION并显示select语句结果(错误消息等)。

但是当我签入数据库时​​,数据将一直提交到失败点。我在这里做错了什么?

更新:回滚数据后,可用的最新标识值会发生变化。 (假设可用的最高身份是10,如果我插入和回滚,则可用的最高身份是11而不是10)。因此回滚不会将数据库返回到事务之前的状态。这就是导致问题的原因。

1 个答案:

答案 0 :(得分:1)

根据您的更新 re:IDENTITY值,这是预期的行为。回滚不会重置IDENTITY值,因此会在ID值中产生间隙。

大概这就是你说“直到失败点之前的数据”的意思 - 而你在交易中更新/插入的所有数据仍然存在于应该回滚。