Why would a process running a transaction at RC isolation level hold an IX page lock if it is already running a select statement on another table? I mean, i thought that locks are released when the statement finishes (that is why we could have non-repeatable reads).
Here's the deadlock 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>
As you can see process process4e13048 holds an IX lock on some page of table WP_CashCenter_StockTransactionLine
. The current statement trying to execute is a SELECT
which cannot finish, because it wants a shared lock on page of WP_Discrepancy
(which is obvious) conflicting with SIX lock held by process process5cd048.
Again, why would the latter process hold that SIX lock? According to execution stack the statement being executed is a SELECT
to WP_CashCenter_StockTransactionLine
table.
I would expect the locks acquired by previous statements within the same process to preserve if I was running a transaction with Serializable IL. But that's not the case.
Can anybody explain me what did I get wrong about RC isolation level.
Thanks.