Предположим, у меня есть 3 запроса, которые выполняются в SSMS в этом порядке.
(1)
select * from MainTableA
(2)
truncate table MainTableA
(3)
select name from MainTableA (nolock) where Id=1
До завершения (1) начинается (2) и до завершения (2), но после его начала начинается (3).
(1) блокирует таблицу IS на MainTableA
(2) ожидает блокировки таблицы Sch-M на MainTableA и блокируется (1)
(3) ожидает блокировки Sch-S на MainTableA и блокируется (2)
Почему (3) блокируется (2)? Поскольку замок Sch-S совместим с замком IS и (2) еще не получил свою блокировку, не следует ли (3) продолжить? Цепочка блокировки показывает, что (2) заблокировано (1) и (3) заблокировано (2), но я не понимаю, почему (2) может блокировать (3), если он еще не получил блокировку.
Почему (3) блокируется (2)? Поскольку замок Sch-S совместим с замком IS и (2) еще не получил свою блокировку, не следует ли (3) продолжить?
Это действительно хороший вопрос, и не очевидно, что он должен быть. На самом деле, это не использовалось для блокировки.
Но текущее поведение заключается в том, что ожидающая блокировка Sch-M блокирует новые запросы на блокировку Sch-S. Таким образом, (3) становится в очередь позади (2) и не получит блокировку Sch-S до тех пор, пока не завершится операция метаданных (здесь TRUNCATE TABLE).
При старом поведении (3) мог продолжаться, но как только он получил свою блокировку Sch-S, он заблокировал бы (2), Затем (4), (5), (6) ... приходите, также получая Sch- S-замки и блокировка (2). И (2) возможно, придется бесконечно долго ждать завершения тихого окна.
Для оперативных операций с базами данных в большинстве случаев лучше, чтобы изменения метаданных выполнялись быстро, и принудительное ожидание новых блокировок Sch-S после ожидающей блокировки Sch-M помогает этому случиться.
Конечно, иногда вы бы предпочли старое поведение, и поэтому недавно оно было повторно введено для определенных операций как «Ожидание с низким приоритетом» вместе с новым поведением тайм-аута. См., например, https://bobsql.com/how-it-works-sql-server-locking-wait_with_low_priority/ и https://www.sqlskills.com/blogs/paul/low-priority-locking- типы ожидания /