我一直试图让这个工作一段时间。
我有一个由另一个开发人员编写的存储过程(我们称之为SPA
),它对数据库进行多次插入,所有这些插入都包装在存储过程的事务中。我还有另一个不使用事务的存储过程(调用它SPB
)。
从我的 .NET 代码中,我还需要将这两个存储过程包装在一个事务中,以确保如果SPB
不成功,则所有内容SPA
都回滚。不幸的是,这对我不起作用。我得到的错误是:
无法回滚 SALE。未找到该名称的事务或保存点。
EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 1,当前计数 = 2。
我已经确认ROLLBACK
或者COMMIT
总是SPA
在退出之前被调用。我的 .NET 代码非常简单:
try {
conn.Open();
trans = conn.BeginTransaction();
prod.Connection = conn;
prod.Transaction = trans;
// Execute SPA
// Execute SPB
} catch (Exception ex) {
trans.Rollback();
} finally {
conn.Close();
}
如果我将 .NET 排除在外,并简单地使用 SSMS 来包装 SP,那么我会得到相同的错误消息。
BEGIN TRAN
DECLARE @return_value int
EXEC @return_value = [dbo].[spSPA] [...]
SELECT 'Return Value' = @return_value
COMMIT TRAN
有任何想法吗?
编辑:
SPA
看起来像:
BEGIN TRY
BEGIN TRAN SALE
IF SomeCondition
DoSomething
ELSE
ROLLBACK TRAN SALE
RETURN 100
IF SomeCondition
DoSomething
ELSE
ROLLBACK TRAN SALE
RETURN 200
...
COMMIT TRAN SALE
RETURN 0
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
ROLLBACK TRAN SALE
END CATCH