2 つのセッションで 2 つのトランザクションが同じアイテムに対して実行されています:
セッション 1 では:
begin tran T1
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders
where item='ItemA'
waitfor delay '00:00:05'
commit T1
セッション 2 では:
begin tran T2
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders
where item='ItemA'
commit T2
このようにすると、2 つの同一の行がテーブル Orders に挿入されます。しかし、どちらかのセッションでトランザクションを実行してから、別のトランザクションで新しい max(OrderNumber) を読み取り、次の値を挿入したいと考えています。次のように T1 にホールドロックを追加します。
begin tran T1
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders with (holdlock)
where item='ItemA'
waitfor delay '00:00:05'
commit T1
SQl SERVER は、select ステートメントを最初に解析してから、insert ステートメントに排他ロックを割り当てるため、最初に select に共有ロックを割り当てますか? 2 つのセッションでロックはどのように相互に機能しますか? ヒントをありがとう