Это хорошая идея для обработки повтора блокировки блокировки блокировки хранимой процедуры

Из того, что я делаю, невозможно полностью предотвратить транзакцию от тупика.

Я хотел бы иметь транзакцию, которая никогда не сработает с точки зрения кода приложения. Таким образом, я видел, как этот шаблон используется для Microsoft SQL, и мне интересно, хорошая ли это идея?

    DECLARE @retry  tinyint
    SET @retry  = 5
    WHILE @retry >0
    BEGIN
      BEGIN TRANSACTION
      BEGIN TRY
        // do transaction her
        COMMIT
        BREAK
      END TRY
      BEGIN CATCH
        ROLLBACK

        if (ERROR_NUMBER() = 1205 OR ERROR_NUMBER() = 1222)
        BEGIN
          SET @retry = @retry - 1
          IF @retry = 0
             RAISEERROR('Could not complete transaction',16,1);
          WAITFOR DELAY '00:00:00.05' -- Wait for 50 ms
          CONTINUE
        END
        ELSE
        BEGIN
          RAISEERROR('Non-deadlock condition encountered',16,1);
          BREAK;
        END
      END CATCH;
    END

Ответ 1

Логика повторения для восстанавливаемых ошибок должна быть в клиентском коде.

Для взаимоблокировок MSDN заявляет, что он там

Если вы повторите попытку в SQL, вы можете в конце концов нажать CommandTimeout.

Существуют и другие ошибки, поэтому вы можете написать общий обработчик

Ответ 2

У вас есть не хорошая идея, так как она вслепую повторяет попытку, не обнаружив фактическую ошибку. Если ошибка была тайм-аутом, например, вы могли бы связать соединение в 5 раз больше времени ожидания, не решая ничего.

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

Вы можете использовать:

IF ERROR_NUMBER() = 1205 

См. документацию для ERROR_NUMBER().