第一道工序:
<deadlock-list>
<deadlock victim="process8d9798">
<process-list>
<process id="process8d9798" taskpriority="0" logused="0" waitresource="PAGE:
5:1:190354" waittime="3203" ownerId="53807810" transactionname="DELETE"
lasttranstarted="11:29:29.153" XDES="0x3dbb518" lockMode="U"
schedulerid="2" kpid="1792" status="suspended" spid="57" sbid="0" ecid="1"
priority="0" transcount="0" lastbatchstarted="2012-09-28T11:29:29.120"
lastbatchcompleted="11:29:29.120" clientapp=".Net SqlClient Data Provider"
hostname="xxx" hostpid="4460" isolationlevel="read uncommitted (1)"
xactid="53807810" currentdb="5" lockTimeout="4294967295" clientoption1="671088672"
clientoption2="128056">
<executionStack>
<frame procname="Chooser2.dbo.DeleteUserSelections" line="15" stmtstart="360"
stmtend="464" sqlhandle="0x030005008839117bf599a500099800000100000000000000">
DELETE UserPlanOption
WHERE UserID = @userId </frame>
</executionStack>
<inputbuf>
</inputbuf>
</process>
第二道工序:
<process id="processb84988" taskpriority="0" logused="1744" waitresource="PAGE:
5:1:190487" waittime="3203" ownerId="53807415" transactionname="user_transaction"
lasttranstarted="11:29:13.513" XDES="0x2fc4e6e0" lockMode="IU"
schedulerid="4" kpid="4628" status="suspended" spid="52" sbid="0" ecid="0"
priority="0" transcount="2" lastbatchstarted="11:29:13.513"
lastbatchcompleted="11:29:13.513"
clientapp=".Net SqlClient Data Provider" hostname="xxx"
hostpid="4460" loginname="chooserpd" isolationlevel="read uncommitted (1)"
xactid="53807415" currentdb="5" lockTimeout="4294967295" clientoption1="671088672"
clientoption2="128056">
<executionStack>
<frame procname="Eligibility" line="149" stmtstart="10566"
stmtend="11604" sqlhandle="0x03000500171b4f52c1a6e200ada000000100000000000000">
UPDATE UserPlanOption
SET RateID = r.ID
FROM [User] u WITH (NOLOCK)
LEFT JOIN Rate r ON r.FamilyTierID = u.FamilyTierID
WHERE UserPlanOption.PlanOptionID NOT IN (SELECT ppo.PlanOptionID FROM
@PORACPlanOptions ppo) AND
u.ID = @userID AND u.ID = UserPlanOption.UserID AND
r.PlanOptionID = UserPlanOption.PlanOptionID AND
r.Criterion1 = dbo.GetPlanOptionAreaID_36()
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 5 Object Id = 1380915991] </inputbuf>
</process>
</process-list>
资源清单:
<resource-list>
<pagelock fileid="1" pageid="190354" dbid="5" objectname="UserPlanOption"
id="lock1e482d80" mode="IX" associatedObjectId="72057594060996608">
<owner-list>
<owner id="processb84988" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process8d9798" mode="U" requestType="wait"/>
</waiter-list>
</pagelock>
<pagelock fileid="1" pageid="190487" dbid="5" objectname="UserPlanOption"
id="lock25b32a80" mode="U" associatedObjectId="72057594060996608">
<owner-list>
<owner id="process8d9798" mode="U"/>
</owner-list>
<waiter-list>
<waiter id="processb84988" mode="IU" requestType="wait"/>
</waiter-list>
</pagelock>
</resource-list>
</deadlock>
</deadlock-list>
表“UserPlanOption 有一个复合 PK(UserId 和 PlanOptionId)。为什么删除会导致页面锁定?有人可以帮我理解这是怎么回事吗?让我困惑的是,我认为死锁是由后续引起的来自同一个客户端的查询,但这是不可能的。这些必须是访问同一个网页的不同客户端。
实际上,我想我知道第一个问题的答案——删除范围需要页面锁定。但我怎样才能解决这个问题?
索引查询的结果:
name type type_desc is_unique data_space_id ignore_dup_key
------------------- ---- --------- --------- ------------- --------------
PK_UserPlanOption_1 1 CLUSTERED 1 1 0
is_primary_key is_unique_constraint fill_factor is_padded is_disabled
-------------- -------------------- ----------- --------- -----------
1 0 0 0 0
is_hypothetical allow_row_locks allow_page_locks
--------------- --------------- ----------------
0 1 1