假设我有两个存储过程,Outer
并且Inner
:
CREATE PROCEDURE dbo.Outer
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRAN
EXEC Inner
-- Perform additional processing (which should not occur if there is
-- a ROLLBACK in Inner)
...
COMMIT
END;
GO
Outer
存储过程打开 XACT_ABORT 并启动显式事务。然后它调用Inner
事务内部的存储过程。
CREATE PROCEDURE dbo.Inner
AS
BEGIN
DECLARE @Id INT=(SELECT Id FROM SomeTable WHERE ...);
IF (@Id IS NOT NULL)
ROLLBACK;
INSERT INTO SomeTable(...)
VALUES (...);
END;
GO
Inner
存储过程执行检查以查看是否存在某些内容,以及是否要回滚在存储过程中启动的整个事务并中止和中的Outer
所有进一步处理。Inner
Outer
发生的事情不是我所期望的,而是我收到了错误消息:
在内部:
EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 1,当前计数 = 0。
在外:
COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION。
显然,ROLLBACK
即使打开了 XACT_ABORT 也不会停止执行流程。在 之后放一条RETURN
语句ROLLBACK
让我们退出Inner
,但Outer
继续执行。我需要做什么才能ROLLBACK
停止所有进一步的处理并有效地导致退出Outer
?
谢谢你的帮助。