【问题标题】:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statementsEXECUTE 之后的事务计数指示 BEGIN 和 COMMIT 语句的数量不匹配
【发布时间】:2015-12-21 23:42:21
【问题描述】:

我正在尝试为存储过程编写日志。我将我的 sp 放在 try 块中,并试图在 catch 块中捕获异常。如果有任何异常,我将回滚交易或提交交易。

USE [RPM_BROKER_TOOL]
GO
/****** Object:  StoredProcedure [dbo].[RPM_PROC_UPDATE_BROKER_SETTINGS]    Script Date: 09/24/2015 16:28:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- AUTHOR     : ROHIT NAIK
-- CREATE DATE: 31-JULY-2015
-- DESCRIPTION: Update Broker Tool settings.
-- =============================================
ALTER PROCEDURE [dbo].[RPM_PROC_UPDATE_BROKER_SETTINGS](
                        @pk_broker_param int,
                        @companyID int,
                        --@BrokerSetting xml
                        @broker_param_id int,
                        @fixed_param_id int,
                        @Exchange_Type varchar(10),
                        @Parameter_Description varchar(100),
                        @DataSize int,
                        @DataType varchar(2),
                        @DataValue varchar(100),
                        @Dialog_Filter varchar(100),
                        @ListOfValues varchar(500),
                        @isMandatory BIT,
                        @CREATED_IN_MODULE varchar(30),
                        @CREATE_LOGIN_NAME varchar(10),
                        @CREATED_ON DATETIME,
                        @Field_Type varchar(5),
                        @Updated_Login varchar(10),
                        @SequenceId int,
                        @Description varchar(1000)          
                        )

AS

DECLARE @Current_Timestamp DATETIME = current_timestamp,
        @RowsInserted int,
        @ErrorMessage varchar(1000),
        @ErrorTable RPM_EXCEPTION_TYPE_TEMP ,
        @ProcName varchar(100)
        --@IN_Pk_Broker_Param int used for auditing

DECLARE @ID_MODULE INT,@DATA_VALUE VARCHAR(500)
SET @ID_MODULE = (SELECT ID_MODULE FROM FW_MODULES WHERE CD_MODULE = 'BROKER APP')
SET @ProcName = (SELECT OBJECT_NAME(@@PROCID))
BEGIN

BEGIN TRY
    BEGIN TRANSACTION

SELECT @DATA_VALUE=DATAVALUE FROM RPM_BROKER_TOOL_CALIBRATION_PARAMETERS WHERE AUDIT_ACTIVE=1 AND FIXED_PARAMETER_ID=@fixed_param_id
IF ISNULL(@DATA_VALUE,'')<>@DataValue
BEGIN
        select 1/0
        INSERT INTO RPM_BROKER_TOOL_CALIBRATION_PARAMETERS(
                        ID_COMPANY,
                        --ID_BROKER_PARAM,
                        FIXED_PARAMETER_ID,
                        EXCHANGE_TYPE,
                        PARAMETER_DESCRIPTION,
                        DATASIZE,
                        DATATYPE,
                        DATAVALUE,
                        DAILOG_FILE_FILTER,
                        LOV,
                        isMandatory,
                        CREATED_IN_MODULE,
                        CREATE_LOGIN_NAME,
                        CREATE_TIME_STAMP,
                        UPDATED_IN_MODULE,
                        UPDATE_LOGIN_NAME,
                        UPDATE_TIME_STAMP,
                        AUDIT_ACTIVE,
                        AUDIT_TYPE,
                        AUDIT_FROM_DATE,
                        AUDIT_TO_DATE,                      
                        SESSION_ID,
                        Field_Type,
                        ID_SEQUENCE,
                        Description
                        )

                VALUES (                        
                        @companyID,
                        --@broker_param_id,
                        @fixed_param_id,
                        @Exchange_Type,
                        @Parameter_Description,
                        @DataSize,
                        @DataType,
                        @DataValue,
                        @Dialog_Filter,
                        @ListOfValues,
                        @isMandatory,
                        @CREATED_IN_MODULE,
                        @CREATE_LOGIN_NAME,
                        @CREATED_ON,
                        @CREATED_IN_MODULE,
                        @Updated_Login,
                        @Current_Timestamp,
                        1,
                        'E',
                        @Current_Timestamp,
                        '12/31/2099',
                        null,
                        @Field_Type,
                        @SequenceId,
                        @Description 
                        )
                    SET @RowsInserted = @@ROWCOUNT

                    SET @ErrorMessage = 'Number of rows updated: ' + convert(varchar(100),@RowsInserted) 
                INSERT INTO @ErrorTable (COMPANY_ID,ID_OBJECT,LOGIN_NAME,MODULE_CODE,PROC_NAME,TIME_STAMP,BUSSINESS_MODULE,EXCEPTION_CATEGORY,EXCEPTION_LEVEL,EXCEPTION_DESCRIPTION)
                VALUES (@companyID,NULL,@CREATE_LOGIN_NAME,@CREATED_IN_MODULE,@ProcName,@Current_Timestamp,NULL,'Information','Normal',@ErrorMessage)

                UPDATE  RPM_BROKER_TOOL_CALIBRATION_PARAMETERS
                SET     AUDIT_ACTIVE = 0, AUDIT_TO_DATE = @Current_Timestamp,
                        UPDATE_TIME_STAMP = @Current_Timestamp, 
                        UPDATE_LOGIN_NAME = @Updated_Login,
                        UPDATED_IN_MODULE = @CREATED_IN_MODULE
                WHERE   PK_BROKER_PARAM = @pk_broker_param


        declare @Update_fields varchar(200)
        set @Update_fields = @Parameter_Description + ' modified'

        EXEC RPM_PROC_INSERT_AUDIT 
        '4016'
        ,@companyID
        ,@pk_broker_param
        --,@fixed_param_id
        ,1 
        ,'E'
        ,@Parameter_Description
        ,@Update_fields
        ,@CREATED_IN_MODULE
        ,@Updated_Login
        ,'BROKER APP SETTINGS'
        ,@CURRENT_TIMESTAMP



END
    COMMIT TRANSACTION
END TRY

BEGIN CATCH

    SET @ErrorMessage = 'Error : ' + ERROR_MESSAGE() + 'on #Line ' + convert(varchar(1000),ERROR_LINE())

    INSERT INTO @ErrorTable (COMPANY_ID,ID_OBJECT,LOGIN_NAME,MODULE_CODE,PROC_NAME,TIME_STAMP,BUSSINESS_MODULE,EXCEPTION_CATEGORY,EXCEPTION_LEVEL,EXCEPTION_DESCRIPTION)
                VALUES (@companyID,NULL,@CREATE_LOGIN_NAME,@CREATED_IN_MODULE,@ProcName,@Current_Timestamp,NULL,'Error','High',@ErrorMessage)
    IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION
END CATCH

    EXEC update_db_log @ErrorTable

END

【问题讨论】:

  • 你的RPM_PROC_INSERT_AUDIT也回滚事务吗?
  • CATCH 块中检查XACT_STATE() 并处理适当的中止和不可提交的交易。无论如何你为什么要使用SELECT 1/0
  • 我猜它也会回滚你的INSERT INTO @ErrorTable ...
  • @lad2025 不,它没有
  • @Abhishek 实际上我使用 select 1/0 作为虚拟异常

标签: sql-server transactions commit rollback


【解决方案1】:

我不知道你为什么会遇到这个问题。但是当我完全按照您的代码完成时,我得到了相同的Transaction Count。这是我的代码:

创建表

CREATE TABLE [dbo].[Test](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [IsActive] [bit] NULL CONSTRAINT [DF_Emails_IsActive]  DEFAULT ((1))
)

SQL

BEGIN TRY
    BEGIN TRANSACTION
        Print(@@TRANCOUNT)
        Print('start')
        Print(@@TRANCOUNT)
        INSERT INTO Test VALUES ('First')
        select 1/0
        Print(@@TRANCOUNT)
        Print('never reach')
        INSERT INTO Test VALUES ('Second')
        Print(@@TRANCOUNT)
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    Print(@@TRANCOUNT)
    Print('catch called')
    INSERT INTO Test VALUES ('Third')
    Print(@@TRANCOUNT)
    Print('inserted')

    IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION
END CATCH
SELECT * FROM Test 

并且Rollback之前的语句也被回滚。 (在你的情况下,INSERT INTO @ErrorTable ... 根据我的评论。)

这是输出:

1
start
1

(1 row(s) affected)

(0 row(s) affected)
1
catch called

(1 row(s) affected)
1
inserted

(0 row(s) affected)

【讨论】:

  • 是的。但是代码在 fe 处抛出 RTE “执行后的事务计数表明开始和提交的数量不匹配”
  • 您是否阅读并检查过这个:stackoverflow.com/a/21930372/1659563 尝试通过评论EXEC RPM_PROC_INSERT_AUDIT...
猜你喜欢
  • 2021-05-23
  • 2015-06-23
  • 2012-02-18
  • 2016-06-21
  • 1970-01-01
  • 2018-03-11
  • 2014-03-22
  • 2014-10-25
  • 2016-07-21
相关资源
最近更新 更多