2012-09-27 120 views
0

我有2个并发进程。在他们里面有一个迭代执行重复验证(选择)+保存(插入)操作。这里是僵局的SQL服务器的探查信息:确定死锁的原因

<deadlock-list> 
    <deadlock victim="process8e09048"> 
     <process-list> 
     <process id="process8e09048" taskpriority="0" logused="1088" waitresource="PAGE: 29:1:376823" waittime="920" ownerId="1276429306" transactionname="user_transaction" lasttranstarted="2012-09-26T20:59:44.367" XDES="0x3077833c0" lockMode="S" schedulerid="1" kpid="4872" status="suspended" spid="79" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2012-09-26T20:59:44.427" lastbatchcompleted="2012-09-26T20:59:44.427" clientapp=".Net SqlClient Data Provider" hostname="PORTAL" hostpid="5348" loginname="IIS APPPOOL\ASP.NET v4.0 Classic" isolationlevel="read committed (2)" xactid="1276429306" currentdb="29" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
     <executionStack> 
     <frame procname="adhoc" line="1" stmtstart="282" sqlhandle="0x02000000b79df8046665e3984d6dc129fec20a3029fce9bc"> 
    SELECT id FROM [WP_CashCenter_StockTransactionLine] WHERE [email protected]_id and [email protected] and [email protected] and [email protected] and id &lt;&gt; @id and Product_id is null and [email protected]_id and StockContainer_id is null and [email protected]_id  </frame> 
     <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> 
    unknown  </frame> 
     </executionStack> 
     <inputbuf> 
    (@id bigint,@StockTransaction_id bigint,@Direction int,@IsVerified bit,@QualificationType int,@Material_id nvarchar(3),@StockLocation_id int)SELECT id FROM [WP_CashCenter_StockTransactionLine] WHERE [email protected]_id and [email protected] and [email protected] and [email protected] and id &lt;&gt; @id and Product_id is null and [email protected]_id and StockContainer_id is null and [email protected]_id </inputbuf> 
     </process> 
     <process id="process5c13948" taskpriority="0" logused="2636" waitresource="PAGE: 29:1:376823" waittime="920" ownerId="1276429252" transactionname="user_transaction" lasttranstarted="2012-09-26T20:59:44.337" XDES="0x222e64e80" lockMode="S" schedulerid="6" kpid="2956" status="suspended" spid="70" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2012-09-26T20:59:44.427" lastbatchcompleted="2012-09-26T20:59:44.427" clientapp=".Net SqlClient Data Provider" hostname="PORTAL" hostpid="5348" loginname="IIS APPPOOL\ASP.NET v4.0 Classic" isolationlevel="read committed (2)" xactid="1276429252" currentdb="29" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
     <executionStack> 
     <frame procname="adhoc" line="1" stmtstart="238" sqlhandle="0x02000000d77dd1038a9b7f6d7158436117c042e42767242d"> 
    SELECT id FROM [WP_CashCenter_StockTransactionLine] WHERE [email protected]_id and [email protected] and [email protected] and [email protected] and id &lt;&gt; @id and Product_id is null and [email protected]_id and StockContainer_id is null and StockLocation_id is null  </frame> 
     <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> 
    unknown  </frame> 
     </executionStack> 
     <inputbuf> 
    (@id bigint,@StockTransaction_id bigint,@Direction int,@IsVerified bit,@QualificationType int,@Material_id nvarchar(3))SELECT id FROM [WP_CashCenter_StockTransactionLine] WHERE [email protected]_id and [email protected] and [email protected] and [email protected] and id &lt;&gt; @id and Product_id is null and [email protected]_id and StockContainer_id is null and StockLocation_id is null </inputbuf> 
     </process> 
     </process-list> 
     <resource-list> 
     <pagelock fileid="1" pageid="376823" dbid="29" objectname="Edsson_WebPortal_v5.01.dbo.WP_CashCenter_StockTransactionLine" id="lock9302c80" mode="IX" associatedObjectId="72057594148028416"> 
     <owner-list> 
     <owner id="process5c13948" mode="IX"/> 
     </owner-list> 
     <waiter-list> 
     <waiter id="process8e09048" mode="S" requestType="convert"/> 
     </waiter-list> 
     </pagelock> 
     <pagelock fileid="1" pageid="376823" dbid="29" objectname="Edsson_WebPortal_v5.01.dbo.WP_CashCenter_StockTransactionLine" id="lock9302c80" mode="IX" associatedObjectId="72057594148028416"> 
     <owner-list> 
     <owner id="process8e09048" mode="IX"/> 
     </owner-list> 
     <waiter-list> 
     <waiter id="process5c13948" mode="S" requestType="convert"/> 
     </waiter-list> 
     </pagelock> 
     </resource-list> 
    </deadlock> 
    </deadlock-list> 

enter image description here

语句与条件选择。这些选择的where子句仅使用包含在非聚集索引中的列。执行计划: enter image description here

+1

您的交易有IX锁,就意味着有更新,删除或插入通过交易这个选择之前完成。 –

+0

堆栈溢出是一个问题解答板,而不是解决问题的机器。如果你需要帮助,你需要把这个问题形成一个问题:解释问题,解释你想做什么,解释你试图纠正它,然后问一个问题。你可能会找到你“橡皮鸭”的答案。 –

+0

@RemusRusanu是的,这是一个带有validate(select)+ insert的循环。 有2个以上的并发进程正在执行这个循环。 –

回答

1

在此死锁图中,两个进程都成功执行INSERT并在同一页面上保存IX锁。他们必须在同一页面的两个单独的行上持有X锁。

由于SELECT被NC索引覆盖,涉及死锁的页面必须属于NC索引。

您的SELECT语句尝试获取已由INSERT语句拥有IX锁的页级锁。

因此,如果您的INSERT不属于相同的StockTransaction_id,只需在SELECT中添加ROWLOCK提示将解决死锁情况。

RCSI保证读者不被作家阻挡,反之亦然。但是如果你的应用程序设计依赖任何阻塞行为,这可能是一个问题。

可以因不同的锁粒度阅读更多关于死锁here