EXECUTE之后的事务计数表示不匹配的BEGIN和COMMIT语句的数量。 前一个计数= 1,当前计数= 0

我有一个插入存储过程将馈送数据到Table1并从Table1中获取Column1值,并调用将提供Table2的第二个存储过程。

但是当我把第二存储过程称为:

Exec USPStoredProcName 

它给我错误如下:

EXECUTE之后的事务计数表示不匹配的BEGIN和COMMIT语句的数量。 前一个计数= 1,当前计数= 0。

我已经阅读了其他这样的问题的答案,我无法find确切的提交计数正在搞砸。

如果您有TRY / CATCH块,那么可能的原因是您正在捕获事务中止exception并继续。 在CATCH块中,您必须始终检查XACT_STATE()并处理适当的被中止和XACT_STATE()提交(注定)事务。 如果你的调用者启动了一个事务,并且这个Calee碰到了一个死锁(终止了这个事务),那么被调用者如何与调用者进行通信,以使事务中止,并且它不应该继续“正常工作”? 唯一可行的办法是重新提出例外情况,迫使主叫方处理这种情况。 如果你默默地吞下一个中止的事务,并且调用者继续假定仍然在原始事务中,那么只有混乱才能确保(并且你得到的错误是引擎试图保护自己的方式)。

我build议你去看看exception处理和嵌套事务 ,它显示了一个可以与嵌套事务和exception一起使用的模式:

 create procedure [usp_my_procedure_name] as begin set nocount on; declare @trancount int; set @trancount = @@trancount; begin try if @trancount = 0 begin transaction else save transaction usp_my_procedure_name; -- Do the actual work here lbexit: if @trancount = 0 commit; end try begin catch declare @error int, @message varchar(4000), @xstate int; select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE(); if @xstate = -1 rollback; if @xstate = 1 and @trancount = 0 rollback if @xstate = 1 and @trancount > 0 rollback transaction usp_my_procedure_name; raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ; end catch end go 

我也有这个问题。 对我来说,原因是我在做

 return commit 

代替

 commit return 

在一个存储过程中。

这通常发生在事务启动时,或者没有提交,或者不是回滚。

如果错误存在于存储过程中,则可以locking数据库表,因为在没有exception处理的情况下由于某些运行时错误导致事务未完成您可以使用下面的exception处理。 SET XACT_ABORT

 SET XACT_ABORT ON SET NoCount ON Begin Try BEGIN TRANSACTION //Insert ,update queries COMMIT End Try Begin Catch ROLLBACK End Catch 

资源

请注意,如果使用嵌套事务,ROLLBACK操作将回滚所有嵌套事务,包括最外层的事务。

这可能会与TRY / CATCH结合使用,导致您所描述的错误。 在这里看到更多。

如果您的存储过程在打开事务后遇到编译失败(例如,表未find,无效的列名称),也会发生这种情况。

我发现我不得不使用2个存储过程一个“工人”一个和包装与try / catch两个与Remus Rusanu概述类似的逻辑。 worker catch用于处理“正常”的失败,包装器捕获来处理编译失败的错误。

https://msdn.microsoft.com/en-us/library/ms175976.aspx

错误不受TRY … CATCH构造的影响

当它们出现在与 TRY … CATCH结构相同的执行级别时 ,以下types的错误不会由CATCH块处理:

  • 编译阻止批处理运行的错误,如语法错误
  • 在语句级别重新编译期间发生的错误,例如由于延迟名称parsing而在编译之后发生的对象名称parsing错误。

希望这可以帮助别人保存几个小时的debugging…

在我的事务中省略了这个语句之后,我遇到了这个错误。

 COMMIT TRANSACTION [MyTransactionName] 

对我来说,经过广泛的debugging,修复是一个简单的丢失; 在回滚之后的捕获语句。 没有它,这个丑陋的错误信息就是你最终的结果。

 begin catch if @@trancount > 0 rollback transaction; throw; --allows capture of useful info when an exception happens within the transaction end catch 

如果你有一个像这样的代码结构:

 SELECT 151 RETURN -151 

然后使用:

 SELECT 151 ROLLBACK RETURN -151