在嵌套存储过程中实现回滚

时间:2014-07-16 11:20:40

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

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

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

/*
statements
*/

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

如果在sp_inner内调用了另一个存储过程sp_first,它也可以执行上述方法,它还执行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

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

3 个答案:

答案 0 :(得分:3)

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

请参阅http://msdn.microsoft.com/en-us/library/ms181299.aspx

上的一般说明

答案 1 :(得分:1)

我建议您查看this link作为示例。基本上,正如podiluska所说,标准回滚将回滚整个事务(意味着,您可以拥有5的trancount并且它将还原所有这些更改)。

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

答案 2 :(得分:1)

我希望下面的代码片段能够明确这个概念。每当在嵌套事务中调用回滚时,它将从最外层事务开始回滚层次结构中的所有事务。因此,当为内部事务调用回滚时,它会自动回滚外部事务,当我们在外部事务中到达Rollback语句时,@@ 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