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