我的问题:是否可以从SQL Server 2005中的另一个存储过程回滚存储过程?
我有SP1将值插入一个表和SP2以将值插入另一个表。 因此,如果在执行SP2时出现任何错误,我也想回滚SP1。
请有人帮我解决我的问题。
谢谢, 巴拉斯
答案 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可以称为独立,因此您需要嵌套事务。 然后你会遇到同样的错误,因为
所以你仍然可以得到错误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