MSSQLServer2008によって選択された犠牲者がデッドロックループの一部ではないという奇妙なデッドロックグラフがあります。このデッドロックはとの間select
ですinsert
。select
デッドロックリソースは、すべてのユーザーが必要とする単一のテーブルです。waitresource = "KEY: 6:72057594098810880 (ffffffffffff)"
質問1:ここでのffffffffffffは、テーブル全体をフルレンジでロックする必要があることを意味しますか?またはキー範囲全体?または、他の何か?
テーブルに主キーID=0の行がないというルールに従っています。この種のチェックを行う場所はほとんどありません。
select foo from bar where @someId = 0 OR SomeId = @someId
。
また、SQLが式を短絡させないことも知りました。したがって、合格@someId = 0
した場合、他の部分が評価されないことを保証するものではありません。したがって、SQLは実行時に実行できる可能性がありますSomeId = @someId
。
質問2:SomeIdで0を見つけることができなかったため、SQLはテーブル全体(または行)の範囲ロックを取得し、他の誰も0idを挿入しません。右?
その仮定を念頭に置いて、where句をこれに変更しました
(CASE
WHEN @someId = 0 THEN 1
WHEN SomeId = @someId THEN 1
ELSE 0
END = 1)
これが評価順序を強制することを期待しています。しかし、私は間違っています。再びデッドロックに陥っています。以下にデッドロックグラフを添付しました。関連するテーブルとsprocの名前を変更しました(会社のポリシー)
質問3:私がここで何が欠けているか知っていますか?
<deadlock-list>
<deadlock victim="process722c508">
<process-list>
<process id="process722c508" taskpriority="0" logused="0" waitresource="KEY: 6:72057594098810880 (ffffffffffff)" waittime="6217" ownerId="24219001" transactionname="SELECT" lasttranstarted="2011-05-17T03:29:16.033" XDES="0x80073a40" lockMode="RangeS-S" schedulerid="13" kpid="20436" status="suspended" spid="91" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2011-05-17T03:29:16.033" lastbatchcompleted="2011-05-17T03:29:16.033" clientapp=".Net SqlClient Data Provider" hostname="SOMEHOST" hostpid="28820" loginname="someloginname" isolationlevel="serializable (4)" xactid="24219001" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="fnGetTableResultAByBId" line="44" stmtstart="2246" stmtend="3566" sqlhandle="0x03000600800d7f0bda124000d99e00000000000000000000">
INSERT INTO @ReturnTable
SELECT Foo, Bar
FROM TheOneTable
WHERE ZId = @zId
AND (CASE
WHEN @yId = 0 THEN 1
WHEN YId = @yId THEN 1
ELSE 0
END = 1)
AND (CASE
WHEN @xId = 0 THEN 1
WHEN XId = @xId THEN 1
ELSE 0
END = 1) </frame>
<frame procname="GetViewCByDId" line="9" stmtstart="272" stmtend="2984" sqlhandle="0x03000600c21629025d8f3f00d99e00000100000000000000">
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 36247234] </inputbuf>
</process>
<process id="process7185048" taskpriority="0" logused="0" waitresource="KEY: 6:72057594098810880 (ffffffffffff)" waittime="6217" ownerId="24218992" transactionname="SELECT" lasttranstarted="2011-05-17T03:29:16.030" XDES="0x179980430" lockMode="RangeS-S" schedulerid="13" kpid="30616" status="suspended" spid="79" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2011-05-17T03:29:16.030" lastbatchcompleted="2011-05-17T03:29:16.030" clientapp=".Net SqlClient Data Provider" hostname="SOMEHOST" hostpid="28820" loginname="someloginname" isolationlevel="serializable (4)" xactid="24218992" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="fnGetTableResultAByBId" line="44" stmtstart="2246" stmtend="3566" sqlhandle="0x03000600800d7f0bda124000d99e00000000000000000000">
INSERT INTO @ReturnTable
SELECT Foo, Bar
FROM TheOneTable
WHERE ZId = @zId
AND (CASE
WHEN @yId = 0 THEN 1
WHEN YId = @yId THEN 1
ELSE 0
END = 1)
AND (CASE
WHEN @xId = 0 THEN 1
WHEN XId = @xId THEN 1
ELSE 0
END = 1) </frame>
<frame procname="GetViewCByDId" line="9" stmtstart="272" stmtend="2984" sqlhandle="0x03000600c21629025d8f3f00d99e00000100000000000000">
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 36247234] </inputbuf>
</process>
<process id="process7223048" taskpriority="0" logused="0" waitresource="KEY: 6:72057594098810880 (ffffffffffff)" waittime="5330" ownerId="24235090" transactionname="SELECT" lasttranstarted="2011-05-17T03:29:16.927" XDES="0x840d3b30" lockMode="RangeS-S" schedulerid="15" kpid="23452" status="suspended" spid="88" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2011-05-17T03:29:16.927" lastbatchcompleted="2011-05-17T03:29:16.927" clientapp=".Net SqlClient Data Provider" hostname="SOMEHOST" hostpid="28820" loginname="someloginname" isolationlevel="serializable (4)" xactid="24235090" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="GetOneRowEByFId" line="11" stmtstart="260" stmtend="2456" sqlhandle="0x03000600db082c08ba823f00d99e00000100000000000000">
SELECT TOP 1
Col1, Col2, Col3
FROM The2ndTable
INNER JOIN [dbo].[TheOneTable] ON [dbo].[TheOneTable].[LinkBetweenOneAndTwoId]=[The2ndTable].[LinkBetweenOneAndTwoId]
WHERE [dbo].[TheOneTable].ZId= @ActivityId and
[TheOneTable].[n
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 137103579] </inputbuf>
</process>
<process id="process6334088" taskpriority="0" logused="0" waitresource="KEY: 6:72057594098810880 (ffffffffffff)" waittime="5668" ownerId="24229434" transactionname="SELECT" lasttranstarted="2011-05-17T03:29:16.587" XDES="0x17ea9ac90" lockMode="RangeS-S" schedulerid="12" kpid="5104" status="suspended" spid="86" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2011-05-17T03:29:16.587" lastbatchcompleted="2011-05-17T03:29:16.587" clientapp=".Net SqlClient Data Provider" hostname="SOMEHOST" hostpid="28820" loginname="someloginname" isolationlevel="serializable (4)" xactid="24229434" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="GetOneRowEByFId" line="11" stmtstart="260" stmtend="2456" sqlhandle="0x03000600db082c08ba823f00d99e00000100000000000000">
SELECT TOP 1
Col1, Col2, Col3
FROM The2ndTable
INNER JOIN [dbo].[TheOneTable] ON [dbo].[TheOneTable].[LinkBetweenOneAndTwoId]=[The2ndTable].[LinkBetweenOneAndTwoId]
WHERE [dbo].[TheOneTable].ZId= @ActivityId and
[TheOneTable].[n</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 137103579] </inputbuf>
</process>
<process id="process8808e08" taskpriority="0" logused="0" waitresource="KEY: 6:72057594098810880 (ffffffffffff)" waittime="6652" ownerId="24217112" transactionname="SELECT" lasttranstarted="2011-05-17T03:29:15.610" XDES="0x833b5ca0" lockMode="RangeS-S" schedulerid="1" kpid="19752" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2011-05-17T03:29:15.610" lastbatchcompleted="2011-05-17T03:29:15.610" clientapp=".Net SqlClient Data Provider" hostname="SOMEHOST" hostpid="28820" loginname="someloginname" isolationlevel="serializable (4)" xactid="24217112" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="GetOneRowEByFId" line="11" stmtstart="260" stmtend="2456" sqlhandle="0x03000600db082c08ba823f00d99e00000100000000000000">
SELECT TOP 1
Col1, Col2, Col3
FROM The2ndTable
INNER JOIN [dbo].[TheOneTable] ON [dbo].[TheOneTable].[LinkBetweenOneAndTwoId]=[The2ndTable].[LinkBetweenOneAndTwoId]
WHERE [dbo].[TheOneTable].ZId= @ActivityId and
[TheOneTable].[n
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 137103579] </inputbuf>
</process>
<process id="process5c08988" taskpriority="0" logused="1644" waitresource="KEY: 6:72057594098810880 (91a0638558d2)" waittime="4889" ownerId="24214248" transactionname="user_transaction" lasttranstarted="2011-05-17T03:29:15.327" XDES="0x186609470" lockMode="RangeI-N" schedulerid="9" kpid="9000" status="suspended" spid="102" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2011-05-17T03:29:15.330" lastbatchcompleted="2011-05-17T03:29:15.330" clientapp=".Net SqlClient Data Provider" hostname="SOMEHOST" hostpid="28820" loginname="someloginname" isolationlevel="serializable (4)" xactid="24214248" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="InsertIntoTheOneTable" line="25" stmtstart="1334" stmtend="2608" sqlhandle="0x03000600bbbacb5d25883f00d99e00000100000000000000">
INSERT INTO [dbo].[TheOneTable] (Some,Col,Here)
VALUES (@some,@col,@here) </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 1573632699] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594098810880" dbid="6" objectname="TheOneTable" indexname="PK_TheOneTable" id="lock6b17a00" mode="RangeI-N" associatedObjectId="72057594098810880">
<owner-list />
<waiter-list>
<waiter id="process722c508" mode="RangeS-S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594098810880" dbid="6" objectname="TheOneTable" indexname="PK_TheOneTable" id="lock6b17a00" mode="RangeI-N" associatedObjectId="72057594098810880">
<owner-list />
<waiter-list>
<waiter id="process7185048" mode="RangeS-S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594098810880" dbid="6" objectname="TheOneTable" indexname="PK_TheOneTable" id="lock6b17a00" mode="RangeI-N" associatedObjectId="72057594098810880">
<owner-list />
<waiter-list>
<waiter id="process7223048" mode="RangeS-S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594098810880" dbid="6" objectname="TheOneTable" indexname="PK_TheOneTable" id="lock6b17a00" mode="RangeI-N" associatedObjectId="72057594098810880">
<owner-list />
<waiter-list>
<waiter id="process6334088" mode="RangeS-S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594098810880" dbid="6" objectname="TheOneTable" indexname="PK_TheOneTable" id="lock6b17a00" mode="RangeI-N" associatedObjectId="72057594098810880">
<owner-list>
<owner id="process5c08988" mode="RangeI-N" />
</owner-list>
<waiter-list>
<waiter id="process8808e08" mode="RangeS-S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594098810880" dbid="6" objectname="TheOneTable" indexname="PK_TheOneTable" id="lock6372e80" mode="RangeS-S" associatedObjectId="72057594098810880">
<owner-list>
<owner id="process7223048" mode="RangeS-S" />
<owner id="process6334088" mode="RangeS-S" />
</owner-list>
<waiter-list>
<waiter id="process5c08988" mode="RangeI-N" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>