2013-11-14 59 views
1

我一直试图让这个工作一段时间。在交易中包装交易存储过程

我有一个存储过程(我们将其称为SPA)由另一位开发人员编写,它将多个插入到数据库中,并且所有这些插入都包装在存储过程中的事务中。我还有另一个不使用事务的存储过程(称为SPB)。

从我的.NET代码中,我需要在事务中包装这两个存储过程,以确保如果SPB不成功,则会回滚所有SPA。不幸的是,这不适合我。我得到的错误是:

无法回滚销售。没有找到该名称的事务或保存点。
EXECUTE后的事务计数表示不匹配的BEGIN和COMMIT语句数。上一个计数= 1,当前计数= 2

我已经证实,ROLLBACKCOMMIT总是被称为内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 
+0

即使您在SPB中创建新的交易,交易也将被独立提交或回滚。 – codemonkeh

+0

@codemonkeh我不想在SPB中创建交易,我想要一个外部交易来同时涵盖SPA和SPB。根据SQL Server中的嵌套事务,内部事务提交(SPA中的)应该被忽略,而我在.NET中的外部事务应该最终提交或回滚所有内容。 – trousyt

+0

啊,你是对的。该错误意味着你错过了一个提交语句。也许你需要在try块中明确地提交它? – codemonkeh

回答

1

我终于发现我的问题。我收到警告Cannot roll back SALE. No transaction or savepoint of that name was found.,因为如果您有嵌套事务,则在回滚时必须指定最外层事务的名称。当然,我不知道那个交易的名字是什么。

解决方法是使用保存点,如TechNet上所述。因此,我必须进行检查以查看是否存在现有交易,如果是,请使用保存点。否则,请自行创建:

DECLARE @TRANCOUNT int 
SET @TRANCOUNT = @@TRANCOUNT 

IF @TRANCOUNT = 0 BEGIN TRAN 
ELSE SAVE TRANSACTION SALE