【问题标题】:Implement rollback in Nested stored procedure在嵌套存储过程中实现回滚
【发布时间】:2014-07-16 19:44:36
【问题描述】:

我正在使用 TRY CATCH 块来捕获错误并进行回滚

ALTER PROCEDURE sp_first
/*
parameters
*/
BEGIN TRY
  BEGIN TRANSACTION

/*
statements
*/

  COMMIT
END TRY
BEGIN CATCH
IF(@@TRANCOUNT>0)
  ROLLBACK
END CATCH

如果在 sp_first 内部调用另一个存储过程 sp_inner,它也执行 DML 语句 INSERT、DELETE、UPDATE 等,上述方法是否有效?

ALTER PROCEDURE sp_first
/*
parameters
*/
BEGIN TRY
  BEGIN TRANSACTION

/*
statements of sp_first
*/

-- stored procedure sp_inner also requires rollback if error occurs.
EXEC sp_inner @paramaterList

  COMMIT
END TRY
BEGIN CATCH
IF(@@TRANCOUNT>0)
  ROLLBACK
END CATCH

如果使用嵌套存储过程,如何实现回滚?

【问题讨论】:

标签: sql sql-server sql-server-2008 tsql


【解决方案1】:

rollback 回滚到最外层事务,而不仅仅是事务中的当前事务。如果这就是你想要做的,那么它会起作用。如果没有,那就不会了。

参见http://msdn.microsoft.com/en-us/library/ms181299.aspx的一般说明

【讨论】:

  • ok ,所以如果所有语句都在外部存储过程sp_first 中成功执行,但在sp_inner 内部发生错误,则将发生完整回滚,即在sp_innner 内部回滚,并且还执行sp_first 语句成功会回滚吗?我想要完全回滚。
  • 我还需要在内部过程sp_inner 中应用开始尝试回滚机制,否则外部存储过程会处理它。
  • 外层会保重的。
【解决方案2】:

我建议以 this link 为例。基本上,正如 podiluska 所说,标准回滚将回滚整个事务(这意味着,您可以有 5 个记录,它会恢复所有这些更改)。

您可以检查 trancount 并仅回滚该数量,但根据链接,我建议在调用嵌套过程之前创建一个保存点,然后在失败时回滚到该保存点。

【讨论】:

    【解决方案3】:

    我希望下面的 sn-p 能让这个概念更清楚。每当在嵌套事务中调用回滚时,它都会从最外层事务开始回滚层次结构中的所有事务。因此,当内部事务调用回滚时,它会自动回滚外部事务,当我们到达外部事务中的回滚语句时,@@trancount 已经为 0,并且在检查后不会执行回滚。

    BEGIN TRANSACTION  
    select @@trancount as 'transactioncount1'
    
     BEGIN TRANSACTION  
        select @@trancount as 'transactioncount2'
    
     ROLLBACK TRANSACTION  
    select @@trancount as 'transactioncount3'
    IF(@@trancount>0)
    ROLLBACK TRANSACTION 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-17
      • 2016-04-08
      • 2020-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多