Повторная попытка запроса в тупиках
В последнее время в нашем имении мы заметили увеличение взаимоблокировок для определенного набора хранимых процедур, это довольно просто:
- Вставить в таблицу
- Обновление записей в таблице на основе первичного ключа
В этой таблице слишком много триггеров, и они иногда конфликтуют с другой хранимой процедурой, которая выполняется ежечасно и приводит к тупику.
Я гуглил и наткнулся на эту статью: 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 ответ
Отказ от ответственности: этот ответ только мнение:)
Похоже, это решение подойдет мне. Однако я не верю, что это реальное решение, но это обходной путь. Вместо этого было бы предпочтительнее попытаться выяснить, что вызывает ваши тупики, и решить это.
Если вы не можете устранить причину взаимоблокировок, то обходной путь, подобный этому, не будет ужасным, но на самом деле просто обходит актуальную проблему.