【问题标题】:Roll back in SQL Server 2005在 SQL Server 2005 中回滚
【发布时间】:2011-08-09 05:52:24
【问题描述】:

我的问题:是否可以从 SQL Server 2005 中的另一个存储过程回滚一个存储过程?

我有 SP1 将值插入一个表和 SP2 将值插入另一个表。 因此,如果在执行 SP2 时出现任何错误,我也想回滚 SP1。

请任何人帮助我解决我的问题。

谢谢, 巴拉特

【问题讨论】:

    标签: sql-server rollback


    【解决方案1】:

    您需要将两个调用包装在一个事务中。

    如果您在 SQL 中调用它们,那么这就是方式,或者使用更全面的版本,例如 7 分钟前 gbn 回答的其他答案。

    create proc doall as
    BEGIN TRY
         BEGIN TRAN
         EXECUTE SP1
         EXECUTE SP1
         COMMIT TRAN
    END TRY
    
    BEGIN CATCH
         ROLLBACK TRAN
    END CATCH;
    

    如果您从其他来源调用 SP,例如从非 SQL 程序,您需要使用 Microsoft 分布式事务协调器 (MSDTC) 服务设置外部事务。

    根据您使用的 API,您可以在代码中设置事务,然后根据条件在代码中提交和回滚。

    例如在 .net 中,您可以使用 System.Transactions 命名空间来创建分布式事务。

    在主程序中

    var tran = new System.Transactions.Transaction();
    
    .
    .
    .
    
    in one piece of code doe a db call (and pass the tran object to the sql connection) so it enlists in the transaction... if it fails - abort the transaction (trans.Rollback())
    
    .
    .
    .
    . 
    
    in another piece of code do another db call (and pass the tran object to the sql connection) so it enlists in the transaction... if it fails - abort the transaction (trans.Rollback())
    .
    .
    .
    later...
    if both pieces of code succeed commit the transaction 
    

    This 是对 this 命名空间的一个很好的介绍,如果您使用的是 .net

    【讨论】:

    • 嗨,preet,实际上我是从另一个窗体调用 SP2,从另一个窗体调用 SP1。那么,如何调用一个普通的 SP。我必须从它调用普通的 SP。跨度>
    • @Bharath:你真的不能这样做。
    【解决方案2】:

    您需要一个包装存储过程来管理事务。

    进入和退出存储过程的@@TRANCOUNT 必须相同,否则会出现错误 266。例如,在启动 TXN 后,您无法退出 SP1。

    我假设 SP1 和 SP2 可以独立调用,因此您需要一个嵌套事务。 然后你遇到了同样的错误,因为

    • BEGIN TRAN 将 @@TRANCOUNT 加一
    • COMMIT TRAN 从@@TRANCOUNT 中减一
    • ROLLBACK 使 @@TRANCOUNT 为零

    所以你仍然可以得到错误 266。

    我的回答在这里解释了更多关于它的信息,包括嵌套、错误 266 抑制等:Nested stored procedures containing TRY CATCH ROLLBACK pattern?

    所以在你的情况下,你需要这样的东西

    CREATE PROCEDURE Wrapper
    AS
    SET XACT_ABORT, NOCOUNT ON
    
    DECLARE @starttrancount int
    
    BEGIN TRY
        SELECT @starttrancount = @@TRANCOUNT
    
        IF @starttrancount = 0
            BEGIN TRANSACTION
    
        EXEC SP1
        EXEC SP2
    
        IF @starttrancount = 0 
            COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        IF XACT_STATE() <> 0 AND @starttrancount = 0 
            ROLLBACK TRANSACTION
        RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
    END CATCH
    GO
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多