Aqui está uma pequena reprodução:
create table dbo.t (id int primary key, v int);
insert into dbo.t values (1, 1), (2, 2);
create table dbo.s (id int primary key, v int);
insert into dbo.s values (1, 10);
go
create trigger dbo.tr_t__iou
on dbo.t
instead of update
as
begin
set nocount on;
exec sp_lock @@spid;
end;
go
update dbo.t set v = 10 where id = 1;
update t
set
v = 10
from
dbo.s s join
dbo.t t on t.id = s.id;
update t
set
v = 10
from
(values (1, 10)) s(id, v) join
dbo.t t on t.id = s.id;
go
drop table dbo.t, dbo.s;
go
sp_lock
dentro dos trigger
relatórios U- key lock
na linha afetada no primeiro e no último caso, mas no segundo caso não há lock
, como isso pode ser explicado?
Quando a instrução de atualização se qualifica para um plano trivial, a regra do otimizador que expande a parte em vez de acionador da instrução (
ExpandInsteadOfTriggerUpd
) inclui a parte do plano que lê a tabela base. Essa reescrita inclui adicionar umaUPDLOCK
dica à leitura base. Como de costume, aUPDLOCK
dica significa que os bloqueios de atualização são obtidos e mantidos até o final da transação.Quando a instrução não se qualifica para um plano trivial, a
ExpandInsteadOfTriggerUpd
regra apenas reescreve a parte do cursor de gravação do plano, deixando as leituras da tabela base intocadas - nenhumaUPDLOCK
dica é adicionada.Meu palpite é que esse comportamento de plano trivial existe para evitar um cenário de impasse.