try / catch中的ROLLBACK TRANSACTION问题

时间:2014-04-21 19:27:56

标签: sql sql-server-2008-r2

当我尝试执行此代码时出现此错误:

EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。先前的计数= 0,当前计数= 1。

我知道问题出现在sp [dbo]。[QueueInsert]上,sp有一个错误,它直接进入catch。这很有趣,因为第一个(EXEC [dbo]。[BacthInsert])正在插入一个摘要记录,在运行sp后,我看到了记录,所以进行提交而不进行回滚。这段代码出了什么问题?谢谢!

CREATE PROCEDURE [cnfg].[SendEmail]
(    
    ,@Employees                 [dbo].[Employees] readonly
    ,@ApplicationName           NVARCHAR(256)
    ,@ErrorMsg                  NVARCHAR(300) = NULL OUTPUT
)
AS
BEGIN

    DECLARE @ReturnVal INT
    DECLARE @ApplicationId UNIQUEIDENTIFIER
    DECLARE @NewIdBatch INT
    DECLARE @ID INT  
    DECLARE @EmployeeId INT 
    DECLARE @Index INT = 1
    DECLARE @Total INT

    SET NOCOUNT ON;
    SET XACT_ABORT ON;        

    SET @ReturnVal = 0;
    SET @ErrorMsg = '';     

    SET @ApplicationId = [GetId](@ApplicationName);        
    IF (@ApplicationId IS NULL)
        BEGIN
            SET @ReturnVal = 1;
            SET @ErrorMsg = 'The Application Name does not exist in the database';
            Goto ProcedureExit
        END

    ----------------------------------------------------------
    BEGIN TRY -- Start Main TRY
    ----------------------------------------------------------

        BEGIN TRANSACTION;

        EXEC [dbo].[BacthInsert]
            @ParameterId                = 1
            ,@ID                        = @NewSendEmailBatchId OUTPUT
            ,@ErrorMsg                  = @ErrorMsg OUTPUT

        IF ( @ErrorMsg <> '' )
            BEGIN
                SET @ReturnVal = 1;
                SET @ErrorMsg = 'There was an error trying to insert data into [dbo].[BacthInsert] table';
                RAISERROR(@ErrorMsg, 16, 1)                
            END     

        SELECT ROW_NUMBER() OVER ( ORDER BY EmployeeId ) Row,
               EmployeeId
          INTO #EmpIds
          FROM @Employees

        SELECT @Total = COUNT(*) FROM #EmpIds

        WHILE ( @Index <= @Total ) 
        BEGIN

            SELECT  @EmployeeId=EmployeeId FROM #EmpIds WHERE Row = @Index

            EXEC [dbo].[QueueInsert]
                @SendEmailBatchId           = @NewIdBatch               
                ,@ID                        = @ID OUTPUT
                ,@ErrorMsg                  = @ErrorMsg OUTPUT

            IF ( @ErrorMsg <> '' )
            BEGIN
                SET @ReturnVal = 1;
                SET @ErrorMsg = 'There was an error trying to insert data into [dbo].[QueueInsert] table';
                RAISERROR(@ErrorMsg, 16, 1)                
            END

            SET @Index+=1;              

        END

        COMMIT TRANSACTION;

    ----------------------------------------------------------
    END TRY -- End Main TRY
    ----------------------------------------------------------

    ----------------------------------------------------------
    BEGIN CATCH -- Start Main CATCH
    ----------------------------------------------------------                              
        SELECT ERROR_MESSAGE()
        IF (XACT_STATE()) = -1
            BEGIN                
                ROLLBACK TRANSACTION;
            END;

    ----------------------------------------------------------
    END CATCH -- End Main CATCH
    ----------------------------------------------------------    

ProcedureExit:
        RETURN @ReturnVal;

END

0 个答案:

没有答案