Блокировка выполнена до того, как выбор определяет максимальное значение, или
после
До, оптимизатором запросов перед его выполнением. В конце концов, это не поможет. Это метод блокировки для оператора, который вы выполняете.
Есть ли условие гонки с вставкой операторов вставки в таблицу
"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 ... .
Не забудьте совершить транзакцию после теста