Как избежать тупика с помощью подсказки NOLOCK - PullRequest
9 голосов
/ 08 июля 2011

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

Транзакция (идентификатор процесса 86) заблокирована для ресурсов блокировки другого процесса и выбрана в качестве жертвы тупика. Перезапустите транзакцию

Кто-то сказал мне, что, если я буду использовать подсказку NOLOCK в своих хранимых процедурах, она никогда не будет заблокирована. Это правильно? Есть ли лучшие способы обработки этой ошибки?

Ответы [ 3 ]

5 голосов
/ 09 июля 2011

Ожидаются случайные тупики в СУБД, которые блокируются как SQL Server / Sybase.

Вы можете написать код на клиенте, чтобы повторить попытку в соответствии с рекомендациями моего MSDN "Обработка тупиковых ситуаций" . В основном, изучите исключение SQLException и, возможно, через полсекунды попробуйте еще раз.

В противном случае вы должны просмотреть свой код, чтобы все доступы к таблицам были в одинаковом порядке. Или вы можете использовать SET DEADLOCK_PRIORITY, чтобы контролировать, кто становится жертвой.

На MSDN для SQL Server есть «Минимизация тупиков» , который запускается

Хотя невозможно полностью избежать тупиков

Здесь также упоминается «Использовать более низкий уровень изоляции», который мне не нравится (как и многие другие типы SQL здесь, в SO), и это ваш вопрос. Не делай так, это ответ ...: -)

Примечание: MVCC типа RDBMS (Oracle, Postgres) не имеют этой проблемы. См. http://en.wikipedia.org/wiki/ACID#Locking_vs_multiversioning, но MVCC имеет другие проблемы.

4 голосов
/ 09 июля 2011

Хотя добавление NOLOCK может помешать читателям и писателям блокировать друг друга (не говоря уже о всех негативных побочных эффектах), это не волшебное исправление для тупиков.Многие взаимоблокировки не имеют никакого отношения к чтению данных, поэтому применение NOLOCK к вашим запросам на чтение может вообще ничего не менять.Вы провели трассировку и изучили график взаимоблокировки, чтобы точно определить, что это за тупик?Это должно по крайней мере дать вам знать, на какую часть кода смотреть.Например, является ли хранимая процедура взаимоблокировочной, потому что она вызывается несколькими пользователями одновременно, или это взаимоблокировка с другим фрагментом кода?

0 голосов
/ 11 июля 2011

Вот хорошая ссылка на обучение устранению тупиков . Я всегда стараюсь избегать использования nolock по вышеуказанным причинам. Также вы можете лучше понять Совместимость блокировок .

...