SQL Server: Tablock, блокировки до или после выбора? - PullRequest
0 голосов
/ 09 ноября 2018

В следующем примере при использовании with (tablockx) выполняется ли блокировка до того, как выбор определяет максимальное значение, или после? Существует ли условие гонки с инструкциями вставки, вставляемыми в таблицу «table1», или гарантируется, что @foo будет содержать максимальное значение, найденное в таблице, до тех пор, пока транзакция не будет зафиксирована или откатана?

begin Transaction

declare @foo int = (select max(col1) from table1 with (tablockx))
-- Is it possible that max(col1) can be > @foo here?

Commit Transaction

Если это имеет значение, я использую SQL Server 2008 R2

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Tablockx получит эксклюзивную блокировку, которая снимается, когда транзакция фиксируется или откатывается. Таким образом, ваша область комментариев будет заблокирована.

0 голосов
/ 09 ноября 2018

Блокировка выполнена до того, как выбор определяет максимальное значение, или после

До, оптимизатором запросов перед его выполнением. В конце концов, это не поможет. Это метод блокировки для оператора, который вы выполняете.

Есть ли условие гонки с вставкой операторов вставки в таблицу "Table1"

Нет, поскольку вы используете TABLOCKX, а не просто TABLOCK. Последний допускает общие блокировки, но вы получаете эксклюзивную блокировку на столе через TABLOCKX.

Гарантируется ли, что @foo будет содержать максимальное значение, найденное в таблица, пока транзакция не будет зафиксирована или откатана

Да, все другие транзакции будут заблокированы (удаление, вставка, обновления и т. Д.)

ИСПЫТАНИЯ

Чтобы проверить это, создайте таблицу и вставьте значение

create table t1_delete (col1 int)
insert into t1_delete
values (1)
go

Далее, на одной панели SSMS запустите ваш код, но закомментируйте COMMIT TRAN

begin Transaction

declare @foo int = (select max(col1) from t1_delete with (tablockx))
-- Is it possible that max(col1) can be > @foo here?
select @foo
--Commit Transaction

Теперь, в новом окне SSMS попробуйте вставить новое значение или что-то еще

insert into t1_delete
values(2)

Вы заметите, что запрос вращается. Вы можете понять, почему, если вы запускаете exec sp_whoIsActive из Адам Механик в другое окно запроса . В частности, проверьте blocking_session_id для вашего сеанса вставки. Это будет сеанс с sql_test, как , начало транзакции, объявление @foo ... .

Не забудьте совершить транзакцию после теста

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...