SQL Server-блокирует ли [SELECT] [UPDATE]?
у меня есть сложный запрос выбора и огромная таблица.
Я select
заявление, а Update
оператор прибывает и пытается обновление столе.
IMHO-обновление требует эксклюзивные lock - поэтому инструкция update должна будет ждать пока команда select не будет завершена.
Я прав ?
что я могу сделать, чтобы: выполнить комплекс
select
, и даupdate
команда "выполнить" (в настоящее время меня не волнуют грязные данные)
2 ответов
Да - до определенной степени.
как долго a SELECT
удерживает общую блокировку в зависимости от уровня изоляции транзакции:
-
READ UNCOMMITTED
- общая блокировка не приобретается вообще -UPDATE
не заблокирован -
READ COMMITTED
- shared блокировка приобретается только на время чтения данных -UPDATE
может быть заблокирован в течение очень короткого периода времени -
REPEATABLE READ
иSERIALIZABLE
- общая блокировка и держался, пока конец сделки -UPDATE
блокируется до тех пор, покаSELECT
транзакция заканчивается
технически UPDATE
оператор сначала получает UPDATE
lock-который совместим с общим замком (как используется SELECT
) - в течение времени, пока он читает текущие значения строк, которые должны быть обновлены.
как только это будет сделано,Update
блокировка повышается до исключительной блокировки для новых данных, которые будут записаны в таблицу.
при одновременном запуске двух операторов (SELECT и UPDATE) фактическое поведение будет в основном случайным. Это происходит потому, что ни одна из операций не является мгновенной. Для упрощения рассмотрим таблицу в виде списка, и SELECT пересекает этот список, просматривая по одной строке за раз. UPDATE также пытается обновить одну или несколько строк. Когда обновление пытается обновить строку за выбор тогда ничего не происходит (без блокировки), потому что выбор уже прогрессировал мимо точки обновления. Если обновление пытается обновить строку, в которой SELECT смотрит прямо сейчас тогда обновление придется ждать, пока SELECT будет двигаться дальше, что произойдет очень очень быстро, и обновление разблокируется и преуспеет, while выбор движется вперед. Но если обновление обновляет строку вперед выберите, тогда обновление будет успешным и,позже, SELECT в конечном итоге достигнет именно этой строки и остановится, блокированный. Теперь выберите должен ждать пока транзакция, которая сделала обновление, не зафиксирует.
это упрощенная история. Реальная жизнь намного сложнее. Выбор может иметь несколько чтение точек (параллельные планы). И SELECT, и UPDATE могут выбрать путь доступа, то есть использовать один или несколько вторичных индексов для поиска строк. Сложные запросы могут содержать операторы, вызывающие несколько поисков в таблице (например. присоединяется.) Оба Выберите и обновление может выполнять поиск закладок для извлечения данных BLOB, что значительно изменяет поведение блокировки. Оценка мощности может привести к запуску SELECT в режиме блокировки высокой детализации (например. общая блокировка уровня таблицы). Обновление может вызвать эскалацию блокировки, и эскалация может завершиться неудачей или успехом. выбор различных путей доступа может привести к взаимоблокировке. ложная блокировка может возникнуть из-за хэш-коллизий. Существует всего около одного мириада переменных это имеет право голоса. И я даже не упомянул о более высоких уровнях изоляции (повторяемое чтение, сериализуемое).
Возможно, вам следует использовать снимок изоляции и перестать беспокоиться об этой проблеме?