为什么我不能在带有Transaction的另一个Procedure中调用Procedure with Transaction?

时间:2017-06-12 12:15:11

标签: sql-server tsql

我有一个proc,它调用另一个proc名称b:

Create PROC a
AS
    BEGIN   
        BEGIN TRY
            BEGIN TRANSACTION;

            IF ( 1 = 1 )
                BEGIN
                    DECLARE @ReturnMessage VARCHAR(50);
                    EXEC dbo.b @ReturnMessage = @ReturnMessage OUTPUT; -- varchar(50)

                    IF ( @ReturnMessage = 'aaaa' )
                    begin
                        PRINT 'anuj';
                        end
                END;
            COMMIT   TRANSACTION;
        END TRY
        BEGIN CATCH
            ROLLBACK TRANSACTION;
        THROW;
        END CATCH;
    END;

b proc是:

Create PROC b
    (
      @ReturnMessage VARCHAR(50) OUTPUT
    )
AS
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
            IF ( 1 = 1 )
                BEGIN

                    ROLLBACK TRANSACTION;
                    SET @ReturnMessage = 'aaaa';
                 RETURN;
                END;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            ROLLBACK TRANSACTION;
            THROW;
        END CATCH;

    END;

当我执行Exec dbo.a

我收到以下消息:

Msg 3903, Level 16, State 1, Procedure a, Line 20 [Batch Start Line 0]
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
Msg 266, Level 16, State 2, Procedure b, Line 0 [Batch Start Line 0]
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.

谁能说我做错了什么?这只是我想要实现的一个例子。是否有更好的方法来处理此类交易

更新:好的,我对proc b进行了以下更改,我使用了事务保存点和Trancount,现在正在使用它:

ALTER PROC b
    (
      @ReturnMessage VARCHAR(50) OUTPUT
    )
AS
    BEGIN
        BEGIN TRY
            DECLARE @trancount INT;
            SET @trancount = @@TRANCOUNT;
            IF @trancount = 0
                BEGIN
                    BEGIN TRANSACTION;
                END;
            ELSE
                BEGIN
                    SAVE TRANSACTION b;

                    IF ( 1 = 1 )
                        BEGIN

                            ROLLBACK TRANSACTION b;
                            SET @ReturnMessage = 'aaaa';
                            RETURN;
                        END;

                END;

            IF ( @trancount = 0 )
                COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @trancount = 0
                BEGIN
                    ROLLBACK TRANSACTION;
                END;
            ELSE
                IF @trancount > 0
                    BEGIN
                        ROLLBACK TRANSACTION b;
                    END;
            THROW;
        END CATCH;

    END;

2 个答案:

答案 0 :(得分:0)

使用throw处理启动事务的过程中的事务...使用@@ TRANCOUNT。

///path/...

答案 1 :(得分:0)

回滚将回滚所有交易。

也许你可以使用保存点。

正如我评论的那样,您可以在回滚/提交之前使用@@ TRANCOUNT来消除错误,或者“合并”它们,而不是独立地嵌套事务。

https://dba.stackexchange.com/questions/82681/how-to-rollback-when-3-stored-procedures-are-started-from-one-stored-procedure/82697

Rollback the inner transaction of nested transaction