【发布时间】:2019-11-27 20:05:38
【问题描述】:
当内部 SP 尝试回滚事务时,它以错误完成:
消息 266,级别 16,状态 2,过程 ptest,第 0 行 [批处理开始行 37] EXECUTE 之后的事务计数指示不匹配的数量 BEGIN 和 COMMIT 语句。先前计数 = 1,当前计数 = 0。
是否可以在内部 SP 内回滚事务?
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ptest]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[ptest] AS'
END
GRANT EXECUTE on [dbo].[ptest] to public;
GO
ALTER PROCEDURE [dbo].[ptest]
@parrollback bit = 0
AS
BEGIN
SET NOCOUNT ON
SET XACT_ABORT OFF
select @@TRANCOUNT as '@@TRANCOUNT:[ptest] '
if @parrollback is not null and @parrollback>0
if @@TRANCOUNT>0 rollback tran;
END
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[pcaller]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[pcaller] AS'
END
GRANT EXECUTE on [dbo].[pcaller] to public;
GO
ALTER PROCEDURE [dbo].[pcaller]
AS
BEGIN
SET NOCOUNT ON
begin tran
select @@TRANCOUNT as '@@TRANCOUNT: before [ptest]'
exec ptest 1
select @@TRANCOUNT as '@@TRANCOUNT: after [ptest] '
if @@TRANCOUNT>0 rollback tran;
END
GO
-------------
exec pcaller
/*
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ptest]') AND type in (N'P', N'PC'))
drop proc pcaller
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ptest]') AND type in (N'P', N'PC'))
drop proc ptest
*/
【问题讨论】:
-
在哪一行出现此错误?
-
dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[pcaller] AS'声明的其余部分在哪里..? -
您的
BEGIN TRAN没有COMMIT;你只有一个ROLLBACK,如果@@TRANCOUNT的值大于0。 -
@Lamu:是的,在调用者中 BEGIN TRAN,然后在内部 proc 这个事务回滚。 FInally trancount=0,但是当我调用 exec pcaller 时它会产生错误。
标签: sql-server tsql