RC分離レベルでトランザクションを実行しているプロセスが、別のテーブルですでにselectステートメントを実行している場合、なぜIXページロックを保持するのでしょうか。つまり、ステートメントが終了するとロックが解放されると思いました(そのため、繰り返し不可能な読み取りが発生する可能性があります)。
デッドロックxmlは次のとおりです。
<deadlock-list>
<deadlock victim="process5cd048">
<process-list>
<process id="process5cd048" taskpriority="0" logused="10000" waittime="2220" schedulerid="3" kpid="5764" status="suspended" spid="62" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2012-11-09T12:16:52.730" lastbatchcompleted="2012-11-09T12:16:52.730" lastattention="2012-11-08T17:33:28.597" clientapp=".Net SqlClient Data Provider" hostname="CWCEINAW" hostpid="4908" loginname="cwcuser" isolationlevel="read committed (2)" xactid="1157173773" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" sqlhandle="0x020000005b3f1719cc3b4ad87e96487fe7fbf624ab5c2984">
SELECT * FROM WP_CashCenter_StockTransactionLine
WHERE [StockTransaction_id] IN (
SELECT DISTINCT [ST].[id]
FROM WP_CashCenter_StockTransaction AS [ST]
LEFT JOIN WP_CashCenter_StockTransactionLine AS [STL] ON ([STL].[StockTransaction_id] = [ST].[id])
WHERE [ST].[Type] IN (1, 0, 10, 9)
AND ([STL].[Direction] IN (1, 0) OR [STL].[id] IS NULL)
AND [ST].[Status] IN (0, 1)
AND ([STL].[StockContainer_id] = 3000080311 OR [ST].[StockContainerID] = 3000080311)) </frame>
</executionStack>
<inputbuf>
SELECT * FROM WP_CashCenter_StockTransactionLine
WHERE [StockTransaction_id] IN (
SELECT DISTINCT [ST].[id]
FROM WP_CashCenter_StockTransaction AS [ST]
LEFT JOIN WP_CashCenter_StockTransactionLine AS [STL] ON ([STL].[StockTransaction_id] = [ST].[id])
WHERE [ST].[Type] IN (1, 0, 10, 9)
AND ([STL].[Direction] IN (1, 0) OR [STL].[id] IS NULL)
AND [ST].[Status] IN (0, 1)
AND ([STL].[StockContainer_id] = 3000080311 OR [ST].[StockContainerID] = 3000080311)) </inputbuf>
</process>
<process id="process33ebc8" taskpriority="0" logused="10676" waitresource="PAGE: 5:1:1144344" waittime="2221" ownerId="1157173773" transactionname="user_transaction" lasttranstarted="2012-11-09T12:16:52.197" XDES="0x41518b140" lockMode="S" schedulerid="5" kpid="5272" status="suspended" spid="62" sbid="0" ecid="9" priority="0" trancount="0" lastbatchstarted="2012-11-09T12:16:52.730" lastbatchcompleted="2012-11-09T12:16:52.730" clientapp=".Net SqlClient Data Provider" hostname="CWCEINAW" hostpid="4908" isolationlevel="read committed (2)" xactid="1157173773" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" sqlhandle="0x020000005b3f1719cc3b4ad87e96487fe7fbf624ab5c2984">
SELECT * FROM WP_CashCenter_StockTransactionLine
WHERE [StockTransaction_id] IN (
SELECT DISTINCT [ST].[id]
FROM WP_CashCenter_StockTransaction AS [ST]
LEFT JOIN WP_CashCenter_StockTransactionLine AS [STL] ON ([STL].[StockTransaction_id] = [ST].[id])
WHERE [ST].[Type] IN (1, 0, 10, 9)
AND ([STL].[Direction] IN (1, 0) OR [STL].[id] IS NULL)
AND [ST].[Status] IN (0, 1)
AND ([STL].[StockContainer_id] = 3000080311 OR [ST].[StockContainerID] = 3000080311)) </frame>
</executionStack>
<inputbuf>
</inputbuf>
</process>
<process id="process4e13048" taskpriority="0" logused="11448" waitresource="PAGE: 5:1:1144209" waittime="2172" ownerId="1157175935" transactionname="user_transaction" lasttranstarted="2012-11-09T12:16:52.997" XDES="0x3458e63b0" lockMode="S" schedulerid="7" kpid="3912" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2012-11-09T12:16:53.070" lastbatchcompleted="2012-11-09T12:16:53.067" clientapp=".Net SqlClient Data Provider" hostname="CWCEINAW" hostpid="4908" loginname="cwcuser" isolationlevel="read committed (2)" xactid="1157175935" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="160" sqlhandle="0x02000000193c8a3bb37a516f7a7155b01a67b7772459f53e">
SELECT [D].*
FROM WP_Discrepancy as [D]
WHERE [D].[Level] = @Level
AND [D].[Status] IN (@StatusInProgress, @StatusConfirmed)
AND [D].[StockContainerID] = @StockContainerID </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
(@Level int,@StatusInProgress int,@StatusConfirmed int,@StockContainerID bigint)SELECT [D].*
FROM WP_Discrepancy as [D]
WHERE [D].[Level] = @Level
AND [D].[Status] IN (@StatusInProgress, @StatusConfirmed)
AND [D].[StockContainerID] = @StockContainerID </inputbuf>
</process>
</process-list>
<resource-list>
<exchangeEvent id="Pipe43a6da400" WaitType="e_waitPipeGetRow" nodeId="1">
<owner-list>
<owner id="process33ebc8"/>
</owner-list>
<waiter-list>
<waiter id="process5cd048"/>
</waiter-list>
</exchangeEvent>
<pagelock fileid="1" pageid="1144344" dbid="5" objectname="WebPortal.dbo.WP_CashCenter_StockTransactionLine" id="lock326ee4180" mode="IX" associatedObjectId="72057594149601280">
<owner-list>
<owner id="process4e13048" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process33ebc8" mode="S" requestType="wait"/>
</waiter-list>
</pagelock>
<pagelock fileid="1" pageid="1144209" dbid="5" objectname="WebPortal.dbo.WP_Discrepancy" id="lock339da6b80" mode="SIX" associatedObjectId="72057594163625984">
<owner-list>
<owner id="process5cd048" mode="SIX"/>
</owner-list>
<waiter-list>
<waiter id="process4e13048" mode="S" requestType="wait"/>
</waiter-list>
</pagelock>
</resource-list>
</deadlock>
</deadlock-list>
ご覧のとおり、プロセスprocess4e13048は、テーブルの一部のページでIXロックを保持していますWP_CashCenter_StockTransactionLine
。実行しようとしている現在のステートメントは、プロセスprocess5cd048によって保持されているSIXロックと競合する(明らかな)SELECT
ページ上の共有ロックが必要なため、終了できません。WP_Discrepancy
繰り返しますが、なぜ後者のプロセスがそのSIXロックを保持するのでしょうか。実行スタックによると、実行されているステートメントはSELECT
toWP_CashCenter_StockTransactionLine
テーブルです。
Serializable ILを使用してトランザクションを実行している場合、同じプロセス内の前のステートメントによって取得されたロックが保持されることを期待します。しかし、そうではありません。
RC分離レベルについて何が間違っていたのか誰かに説明してもらえますか?ありがとう。