Подтвердить что ты не робот

Сбой транзакции для выбранного запроса

Иногда у меня есть следующая ошибка для хранимой процедуры, которая является только запросом Select: Transaction (Process ID 91) was deadlocked on lock

Мое первоначальное понимание заключалось в том, что запрос select не блокирует таблицу или не вызывает тупик, даже если запрашиваемая таблица обновляется/блокируется другим процессом, но кажется, что запрос select может также вызывают взаимоблокировки.

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

4b9b3361

Ответ 1

Мое понимание состоит в том, что Select запрос не будет блокировать таблицу или не будет вызывают тупик

Это понимание неверно. В запросах SELECT используются общие блокировки для строк, которые они анализируют. Общие блокировки могут конфликтовать с исключительными блокировками из операторов update/delete/insert. Два оператора SELECT не заходят в тупик, но SELECT может затормозить с помощью UPDATE. Когда такой тупик происходит, SELECT обычно является жертвой, так как он не выполняет никакого обновления, поэтому всегда будет потерять ничью.

Как и в любом тупике, вам нужно разместить точную схему соответствующих таблиц, точные инструкции T-SQL и график взаимоблокировки. См. Практическое руководство. Сохранение графиков взаимоблокировок (профилировщик SQL Server). С помощью этой информации вы можете получить руководство по устранению тупика.

Ответ 2

Как говорит Ремус, вы получаете блокировки, потому что операции SELECT и UPDATE (или другие) блокируют друг друга, а не SELECT vs SELECT. Вам придется посмотреть на все ваши запросы, касаясь этой таблицы, и создать соответствующие индексы покрытия для этих запросов, и это решит ваши проблемы. Хорошие индексы покрытия являются предпочтительным решением вместо использования табличных подсказок WITH (NOLOCK).

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

Ответ 3

Если вы используете SQL Server 2008, вы можете установить уровень изоляции, чтобы читать uncommitted, чтобы предотвратить тупик. См. Ссылку . При чтении uncommitted или WITH (NOLOCK) необходимо знать, что данные, полученные в результате запроса, могут быть НЕ РЕАЛЬНЫМИ!