2012-07-18 32 views
0

停止执行比方说,我有两个存储过程,OuterInner如何回滚,并从内部存储过程

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存储过程开始和终止两InnerOuter所有进一步的处理。

出现这种情况的,而不是我所期望的如上面概括的事情,是我得到的错误信息:

在内蒙古:

事务计数后EXECUTE表示 失配数BEGIN和COMMIT语句。先前计= 1,当前计数= 0

在外层:

TRANSACTION请求没有相应的BEGIN事务的提交。

显然,即使启用了XACT_ABORT,ROLLBACK也不会停止执行流程。在ROLLBACK之后发出RETURN声明使我们脱离Inner,但Outer中的执行继续。我需要做什么才能使ROLLBACK停止所有进一步处理并有效地退出Outer

感谢您的任何帮助。

+1

我不是100%肯定的,但是如果你在Inner过程中做了RAISERROR而不是回滚呢?我认为它应该导致调用事务回滚。 – King 2012-07-18 18:06:27

+0

交易保存点 – 2012-07-18 18:17:09

+0

它是否符合我们的要求? – 2012-07-24 16:46:10

回答

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 
1

发行回滚不会中止批次(无论XACT_ABORT设置)。如果在严重程度较高的情况下抛出错误 - 系统或通过RAISERROR生成自定义,批处理将自动中止您的案例。