Повторная попытка запроса в тупиках

В последнее время в нашем имении мы заметили увеличение взаимоблокировок для определенного набора хранимых процедур, это довольно просто:

  • Вставить в таблицу
  • Обновление записей в таблице на основе первичного ключа

В этой таблице слишком много триггеров, и они иногда конфликтуют с другой хранимой процедурой, которая выполняется ежечасно и приводит к тупику.

Я гуглил и наткнулся на эту статью: https://www.simple-talk.com/sql/database-administration/handling-deadlocks-in-sql-server/

Для обработки процедур взаимоблокировки предлагается следующий шаблон:

DECLARE @retries INT ;
SET @retries = 4 ;

WHILE ( @retries > 0 ) 
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION ;

         -- place sql code here
            SET @retries = 0 ;

            COMMIT TRANSACTION ;
        END TRY
        BEGIN CATCH 
        -- Error is a deadlock
            IF ( ERROR_NUMBER() = 1205 ) 
                SET @retries = @retries - 1 ;

        -- Error is not a deadlock
            ELSE 
                BEGIN
                    DECLARE @ErrorMessage NVARCHAR(4000) ;
                    DECLARE @ErrorSeverity INT ;
                    DECLARE @ErrorState INT ;

                    SELECT  @ErrorMessage = ERROR_MESSAGE() ,
                            @ErrorSeverity = ERROR_SEVERITY() ,
                            @ErrorState = ERROR_STATE() ;

                    -- Re-Raise the Error that caused the problem
                    RAISERROR (@ErrorMessage, -- Message text.
                       @ErrorSeverity, -- Severity.
                       @ErrorState -- State.
                       ) ;
                    SET @retries = 0 ;
                END

            IF XACT_STATE() <> 0 
                ROLLBACK TRANSACTION ;
        END CATCH ;
    END ;
GO 

Это в значительной степени дает коду второй, третий и четвертый шанс на успех, и только после этого выдает ошибку.

Мой вопрос заключается в том, является ли это здоровым шаблоном для устранения тупиковых ситуаций в сложных ситуациях и является ли это реальным решением, а не обходным решением проблемы?

1 ответ

Решение

Отказ от ответственности: этот ответ только мнение:)

Похоже, это решение подойдет мне. Однако я не верю, что это реальное решение, но это обходной путь. Вместо этого было бы предпочтительнее попытаться выяснить, что вызывает ваши тупики, и решить это.

Если вы не можете устранить причину взаимоблокировок, то обходной путь, подобный этому, не будет ужасным, но на самом деле просто обходит актуальную проблему.

Другие вопросы по тегам