ここに小さな再現があります:
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
trigger
レポートU -key lock
最初のケースと最後のケースで影響を受けた行にありますが、2番目のケースではlock
がまったくありません。どのように説明できますか?
Updateステートメントが取るに足らないプランに該当する場合、ステートメントの代わりのトリガー部分(ExpandInsteadOfTriggerUpd
)を展開するオプティマイザールールには、ベーステーブルから読み取るプランの部分が含まれます。この書き換えには、ベースの読み取りにUPDLOCK
ヒントを追加することが含まれます。通常どおり、UPDLOCK
ヒントは、更新ロックが取得され、トランザクションの最後まで保持されることを意味します。
ステートメントが簡単なプランに適さない場合、ExpandInsteadOfTriggerUpd
ルールのみ プランの書き込みカーソル部分を書き換えます 、基本テーブルはそのまま残ります-UPDLOCK
ヒントが追加されました。
私の推測では、この平凡な計画の振る舞いは、デッドロックシナリオを回避するために存在していると思います。