假设我有两个存储过程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
存储过程中启动的整个事务并中止{{1}中的所有进一步处理}和Inner
。
发生的事情不是我上面所概述的,而是我收到错误消息:
在内心:
EXECUTE之后的事务计数表示不匹配的数量 BEGIN和COMMIT语句。先前的计数= 1,当前计数= 0。
在外面:
COMMIT TRANSACTION请求没有相应的BEGIN TRANSACTION。
显然,即使启用了XACT_ABORT,Outer
也不会停止执行流程。在ROLLBACK
之后添加RETURN
语句会使我们离开ROLLBACK
,但Inner
中的执行仍在继续。我需要做些什么才能使Outer
停止所有进一步处理并有效退出ROLLBACK
?
感谢您的帮助。
答案 0 :(得分:1)
发出回滚不会中止批处理(无论XACT_ABORT设置如何)。如果在严重程度足够高的情况下抛出错误 - 系统或通过RAISERROR生成的自定义,批处理将自动中止。
答案 1 :(得分:0)
您必须实施Exception Handling
Begin Try
Set NOCOUNT ON
SET XACT_ABORT ON
Begin Tran
--Your Code
Commit Tran
End Try
Begin Catch
Rollback Tran
End Catch