并行插入存储过程在SQL SERVER中失败

时间:2016-05-03 12:05:43

标签: sql-server stored-procedures parallel-processing locking isolation-level

以下SP在多个线程中并行运行时失败。 试图在SP中使用不同的隔离级别,但我仍面临同样的错误。

  

违反UNIQUE KEY约束   ' AK_MerchantTransactionEnd_MerchantReferenceCode_BankReferenceCode&#39 ;.   无法在对象' dbo.EpayTransaction'中插入重复键。该   重复键值为(20160503171525689435,20160329221725169,0)。

表具有MerchantReferenceCode_BankReferenceCode的UNIQUE约束

CREATE PROCEDURE [dbo].[uspUpdateEpayConfirmation]
    @merchantReferenceCode VARCHAR(30) ,
    @bankGatewayCode VARCHAR(30) ,
    @transactionNumber VARCHAR(100) 
AS
    BEGIN
      SET NOCOUNT ON;
      SET XACT_ABORT ON;

     BEGIN TRY

        DECLARE @timestamp DATETIME;
        SET @timestamp = GETDATE();
        IF EXISTS ( SELECT  1
                    FROM    [dbo].EpayTransaction WITH (NOLOCK)
                    WHERE   [dbo].EpayTransaction.[MerchantReferenceCode] = @merchantReferenceCode 
                  )
            BEGIN
                RETURN 0;
            END;

        SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

        BEGIN TRANSACTION;
        -- update the epayment transaction information with the merchent reference code

             -- updating the status of the transaction 
        UPDATE  [dbo].[CustomerTransaction]
        SET     [dbo].[CustomerTransaction].[ModifiedBy] = 1 ,
                [dbo].[CustomerTransaction].[ModifiedOn] = @timestamp
        WHERE   [dbo].[CustomerTransaction].[MerchantReferenceCode] = @merchantReferenceCode;

            -- adding a record to EpayTransaction table  to conclude the transaction is successful
        INSERT  INTO [dbo].EpayTransaction
                ( [dbo].EpayTransaction.[BankReferenceCode] ,
                  [dbo].EpayTransaction.[BankTransactionDate] ,
                  [dbo].EpayTransaction.[MerchantReferenceCode]
                )
        VALUES  ( @bankGatewayCode ,
                  @timestamp ,
                  @merchantReferenceCode
                );
        COMMIT TRANSACTION;

        RETURN 1;
    END TRY

    BEGIN CATCH

        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;

    -- Raise an error with the details of the exception
        DECLARE @errMsg NVARCHAR(4000) ,
            @errSeverity INT;

        SELECT  @errMsg = ERROR_MESSAGE() ,
                @errSeverity = ERROR_SEVERITY();

        RAISERROR(@errMsg, @errSeverity, 1);
    END CATCH;

END;

0 个答案:

没有答案