在SQL Server 2005中回滚

时间:2011-08-09 05:52:25

标签: sql-server rollback

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

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

请有人帮我解决我的问题。

谢谢, 巴拉斯

2 个答案:

答案 0 :(得分: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;

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

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

例如,在.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 
如果你使用.net

This是对这个命名空间的一个很好的介绍

答案 1 :(得分: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?

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

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