2011-08-09 53 views
0

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

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

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

感谢, 巴拉斯

回答

2

您需要包装在一个事务中两个通话。

如果你在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; 

如果你从另一个源,如从非SQL程序调用的SP,你需要设置使用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是一个很好的介绍这个命名空间,如果你正在使用.NET

+0

嗨普里特,其实荫调用从另一个从另一个form.So的SP2和SP1,怎么可能到拨打的共同SP.from我不得不称之为普通SP。 – Bharath

+0

@Bharath:你不能这样做。 – gbn

0

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

@@ TRANCOUNT在进入和退出存储过程时必须相同,否则会得到错误266.因此,例如,您不能退出启动TXN的SP1。

我认为SP1和SP2可以被称为独立,所以你需要一个嵌套事务。 然后你打了同样的错误,因为

  • BEGIN TRAN增加一个对@@ TRANCOUNT
  • COMMIT TRAN减去一个从@@ TRANCOUNT
  • ROLLBACK使@@ TRANCOUNT零

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

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

所以你的情况,你需要soemthing这样

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