我收到以下错误:
EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。先前的计数= 0,当前计数= 1.
当我尝试执行此存储过程时:
create procedure [dbo].[SynchCustomerSubscriptions] (
@subscriptions Subscriptions readonly )
as
begin transaction
begin tran SynchTransaction
begin try
delete s
from Subscription s (nolock)
where s.Customer in (
select Customer
from @subscriptions)
exec AddSubscriptions
@subscriptions
end try
begin catch
rollback tran SynchTransaction
return
end catch
commit tran SynchTransaction
有没有人发现问题?
答案 0 :(得分:3)
begin transaction
begin tran SynchTransaction
有时候你看这些东西太久了,最简单的事情就是逃避你。
答案 1 :(得分:0)
试试这个......
create procedure [dbo].[SynchCustomerSubscriptions] (
@subscriptions Subscriptions readonly )
as
begin transaction SynchTransaction
begin tran
begin try
delete s
from Subscription s (nolock)
where s.Customer in (
select Customer
from @subscriptions)
exec AddSubscriptions
@subscriptions
end try
begin catch
rollback tran SynchTransaction
return
end catch
end tran
commit transaction SynchTransaction
答案 2 :(得分:0)
在存储过程中启动命名的事务实际上非常糟糕。如果在另一个事务的范围内调用该过程,则不可能仅回滚命名事务,如您明显尝试的那样,请参阅MSDN:
在a中命名多个事务 一系列带嵌套的事务 事务名称影响不大 交易。只有第一个 (最外面)的交易名称是 在系统注册。回滚 任何其他名称(有效的除外) 保存点名称)生成错误。
你可能想要的是一个保存点,它是一种不同的野兽。如果要混合嵌套事务,保存点和异常try / catch块,事情就会复杂一些。最好使用类似于本文Exception handling and nested transactions的模式,该模式考虑当前@@TRANCOUNT
和异常XACT_STATE
:
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) ;
return;
end catch
end