Поначалу это казалось таким легким, но все, что я знаю, снова кажется неправильным.
Глядя на PAQ, кажется, что консенсус заключается в том, что EXEC не запускает неявную транзакцию, вы можете проверить это, выполнив:
create procedure usp_foo
as
begin
select @@trancount;
end
go
exec usp_foo;
, который возвращает 0.
Однако, если вы пройдете через это с помощью отладчика T-SQL, @@ Транзакция фактически равна 1 внутри процедуры согласно наблюдению, хотя она возвращает 0 ...
Так что я думаю, что это побочный эффект отладчика, но затем я пишу некоторый код для его тестирования, обновляю таблицу и затем выбираю max (id) из классического:
create table nextid
(
id int
)
insert into nextid values (0)
create procedure nextid
as
BEGIN
UPDATE nextid set id = id + 1
select max(id) from nextid
END
Таким образом, я ожидаю, что это выдаст дубликаты идентификаторов, поскольку они выполняются параллельно. Обновления 2 могут быть завершены до того, как 2 выберет выбор последнего идентификатора и возврат одного и того же значения, но, пытаясь ударить его с нескольких машин, я не могу его сломать. , При мониторинге блокировок и транзакций на компьютере он сообщает, что exec происходит в транзакции, и, что важно, все операторы внутри exec обрабатываются как одна единица работы / одна транзакция.
Я бы понял, если обновление было в транзакции, и это было причиной блокировки, но кажется, что блокировка сохраняется до после выбора.
Если я выполняю трассировку с помощью профилировщика, я вижу, что идентификатор транзакции предоставляется для всего выполнения оператора EXEC, и идентификатор транзакции не равен 0, как я ожидаю при выполнении ...
Может кто-нибудь объяснить мне, где я скучаю по сюжету, или я ошибаюсь, и на самом деле безопасно генерировать такие идентификаторы?