Предположим, у меня есть следующий длительный запрос
UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
и предположим, что следующий запрос выполняется во время выполнения вышеуказанного запроса
SELECT *
FROM [Table1]
Предотвращает ли первый запрос выполнение второго запроса до тех пор, пока не будет выполнен первый запрос? Если да, предотвращает ли первый запрос выполнение второго запроса на всех строках или только на строках, включенных в предложение WHERE?
РЕДАКТИРОВАТЬ:
Предположим, что второй запрос
SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
-- the clause in the first query and which has additional matching elements
источник
SELECT * FROM Table1
если это именно то, что мне нужно?*
само по себе это плохая практика, потому что при изменении структуры таблицы приложение обычно ломается (в результате появляются неожиданные столбцы).Редактировать: Как указывает @MaxVernon , следующее ни в коем случае не является предложением использовать NOLOCK , и я очень хорошо должен был упомянуть, что установил уровень транзакции
READ UNCOMMITED
и позволил негативной коннотации стоять там, чемNOLOCK
подниматься в первую очередь. Итак, как первоначально размещено:Быстрый и простой ответ: «Да, первый запрос заблокирует второй запрос, если не указана определенная подсказка индекса ( NOLOCK , иногда называемая« грязным чтением »), или если уровень изоляции транзакции второго запроса установлен на
READ UNCOMMITED
(который работает идентично), нет."В ответ на дополнительные детали, представленные в вопросе, которые влекут за собой включение
WITH
второго предложенияSELECT
, являющегося взаимоисключающим или иным образом, взаимодействия между этими двумя запросами будут в основном одинаковыми.В отдельном сеансе выполните следующее:
Вы можете проверить блокировки, которые в настоящее время удерживаются, запустив
sp_lock
, желательно в еще одном отдельном сеансе:Вы должны увидеть, что
KEY
блокировка типа удерживается спидом, выполняющим транзакцию вставки вX
(исключительном) режиме, не путаясь с другимиIX
( намеренно исключающими ) блокировками. Документация о блокировке указывает, что хотяKEY
блокировка зависит от диапазона, она также не позволяет другим транзакциям вставлять или обновлять затронутые столбцы, изменяя содержащиеся в них данные, чтобы они могли попадать в этот диапазон исходного запроса. Поскольку удерживаемая блокировка является исключительной, первый запрос запрещает доступ к ресурсу из любой другой параллельной транзакции. Фактически все строки столбца блокируются независимо от того, попадают ли они в диапазон, указанный в первом запросе.Таким образом,
S
блокировка, удерживаемая вторым сеансом, будетWAIT
действовать до тех пор, покаX
блокировка не будет снята , не позволяя другойX
(илиU
) блокировке принять этот ресурс с другого параллельного spid до того, как второй сеанс завершит свою операцию чтения, оправдывая существованиеS
блокировки.Теперь отредактируйте для ясности: если я не ошибаюсь в том, что грязное чтение взято из краткого описания рисков, упомянутых здесь ... Редактировать 3 : Я только что понял, что не рассматриваю эффект фоновой контрольной точки, которая пишет как о еще не совершенной транзакции на диск, так что да, мое объяснение вводило в заблуждение.
Во втором запросе первая партия может (и в этом случае будет) возвращать незафиксированные данные. Второй пакет, работающий с уровнем изоляции транзакции по умолчанию
READ COMMITED
, вернется только после завершения фиксации или отката в первом сеансе.Отсюда вы можете посмотреть свои планы запросов и соответствующие уровни блокировки, но, что еще лучше, вы можете прочитать все о блокировках в SQL Server здесь .
источник
WITH (NOLOCK)
этом случае было бы полезно предупредить об использовании . См. Brentozar.com/archive/2011/11/… и brentozar.com/archive/2013/02/… для получения дополнительной информации.WITH (NOLOCK)
подсказка не возвращает грязные страницы из памяти, которые не были зафиксированы. На самом деле он читает строки из таблицы (будь то на диске или кэшированные в памяти), не блокируя писателей от обновления или добавления строк на страницы, используемые таблицей.