关于此SQL语句的ROLLBACK TRANSACTION的任何想法

时间:2011-11-16 08:45:10

标签: sql sql-server rollback

有人可以帮我解决这个SQL语句。我在SQL Server引擎上运行它。

我有以下语句删除表中的所有条目并用新的条目替换它们:

SET XACT_ABORT ON;
BEGIN TRANSACTION;
DELETE FROM [t1] WHERE [id]>10;
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
--and so on, I may have up to 100 of these inserts
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
COMMIT;
SET XACT_ABORT OFF;

我想知道的是,如果上述交易失败,您如何使用ROLLBACK?

PS。我基本上需要将数据库恢复到以前在上述语句中出现任何错误时的情况。

修改 更新了SET XACT_ABORT ON;声明如下。是它应该看起来怎么样?

5 个答案:

答案 0 :(得分:4)

如果您希望事务完全回滚错误,则需要设置SET XACT_ABORT ON

将此设置为ON,如果任何语句失败,则事务将回滚。您无需致电ROLLBACK即可。

在这种情况下,当您使用BEGIN TRANSACTION时,每个语句都将成为该事务的一部分,这意味着它们将全部运行或全部失败。如果在COMMIT之前发生错误,则事务将回滚,并且您的数据库将处于与BEGIN TRANSACTION之前相同的状态(假设没有其他客户端同时更改数据库)。

请参阅XACT_ABORT的文档。

答案 1 :(得分:4)

@Oded已经介绍了一种自动处理回滚的好方法。为了完整起见,我将为您提供另一种方法来使用try catch显式处理该情况。

BEGIN TRANSACTION;

BEGIN TRY
    DELETE FROM [t1] WHERE [id]>10;
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
    --and so on, I may have up to 100 of these inserts
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

答案 2 :(得分:1)

答案 3 :(得分:1)

您没有提及SQL Server的版本 - 但从2005版本开始,您可以使用BEGIN TRY... END TRY BEGIN CATCH... END CATCH样式异常处理。

我通常将我的语句块包装在事务/ try-catch块框架中,如下所示:

BEGIN TRANSACTION
BEGIN TRY

    -- put your statements to be executed *HERE*    

    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

    ROLLBACK TRANSACTION
END CATCH

该块尝试执行我的语句 - 如果成功,则提交事务,如果发生异常,执行跳转到CATCH块,打印出详细的错误信息,并回滚事务

答案 4 :(得分:0)

您可以尝试以下方法:

BEGIN TRY
   BEGIN TRANSACTION 
     DELETE FROM tablename WHERE id>1
     --- set of your querys 
    COMMIT
END TRY

BEGIN CATCH 
    IF @@TRANCOUNT > 0  
       ROLLBACK 
END CATCH