这是一个奇怪的发现。我正在一个会话上进行选择和删除,并在同一行的另一个会话中删除,请参阅下面的代码。 departmentid有聚集索引。
------Session 1----------
set transaction isolation level repeatable read
begin transaction
select * from HumanResources.Department
------session 2 ------------
set transaction isolation level repeatable read
begin transaction
delete from HumanResources.Department
where departmentid = 9
--session 1 -----------
delete from HumanResources.Department
where departmentid = 9
这是应该发生的事情。
delete
语句并且应该对该行设置[u]
锁,然后尝试将u
锁定转换为X
锁定,因为会议1 s
锁
delete
语句尝试将X
锁定,但被会话2的u
锁定阻止。因此发生死锁。 然而,当我看到死锁图时,我得到了不同的图片。死锁图表示会话1授予S锁定。第2节授予X锁(我在这里有困惑)如何在S锁上授予x锁。请参阅下面的死锁图:
<victimProcess id="process5d1a718"/>
<process-list>
<process id="process5d1a718" taskpriority="0" logused="0" waitresource="KEY: 7:72057594073907200 (15ac4ff5e281)" waittime="2723" ownerId="21790" transactionname="user_transaction" lasttranstarted="2016-03-06T15:44:12.863" XDES="0x6056c08" lockMode="X" schedulerid="2" kpid="6016" status="suspended" spid="52" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-03-06T15:44:53.147" lastbatchcompleted="2016-03-06T15:44:12.863" clientapp="Microsoft SQL Server Management Studio" hostname="SAMAR-PC" hostpid="3620" loginname="samar-PC\samar" isolationlevel="repeatable read (3)" xactid="21790" currentdb="7" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<executionStack>
<frame procname="" line="1" stmtstart="24" sqlhandle="0x0200000033392c164aa2164aaf9c828974edf396604cba95">
</frame>
<frame procname="" line="1" sqlhandle="0x02000000e46e292caa2d578b8876190ff31f36bfdf42b892">
</frame>
</executionStack>
<inputbuf>
delete from HumanResources.Department
where departmentid = 9 </inputbuf>
</process>
<process id="process19b1c8" taskpriority="0" logused="0" waitresource="KEY: 7:72057594074103808 (10aa4711661d)" waittime="21212" ownerId="21981" transactionname="user_transaction" lasttranstarted="2016-03-06T15:44:34.657" XDES="0x6b4c280" lockMode="X" schedulerid="1" kpid="4148" status="suspended" spid="55" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-03-06T15:44:34.657" lastbatchcompleted="2016-03-06T15:43:36.970" lastattention="2016-03-06T15:33:58.423" clientapp="Microsoft SQL Server Management Studio - Query" hostname="SAMAR-PC" hostpid="3620" loginname="samar-PC\samar" isolationlevel="repeatable read (3)" xactid="21981" currentdb="7" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<executionStack>
<frame procname="" line="3" stmtstart="24" sqlhandle="0x0200000033392c164aa2164aaf9c828974edf396604cba95">
</frame>
<frame procname="" line="3" stmtstart="136" sqlhandle="0x02000000c3907d12b9a0c511ab9b3c2966aa00fd5258d812">
</frame>
</executionStack>
<inputbuf>
set transaction isolation level repeatable read
begin transaction
delete from HumanResources.Department
where departmentid = 9 </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594073907200" dbid="7" objectname="" indexname="" id="locka1d5040" mode="X" associatedObjectId="72057594073907200">
<owner-list>
<owner id="process19b1c8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process5d1a718" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594074103808" dbid="7" objectname="" indexname="" id="locka1d4780" mode="S" associatedObjectId="72057594074103808">
<owner-list>
<owner id="process5d1a718" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="process19b1c8" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
</value>
<text />
</data>
</event>
</RingBufferTarget>
我有另一个发现,这也很奇怪。如果我更改了会话1的select语句,那就是我在其中添加where子句,我没有遇到任何死锁。我只看到会话2被阻止,会话1用departmentid = 9删除该行。请参阅下面的查询: -
------Session 1----------
set transaction isolation level repeatable read
begin transaction
select * from HumanResources.Department
where departmentid = 9
------session 2 ------------
set transaction isolation level repeatable read
begin transaction
delete from HumanResources.Department
where departmentid = 9
--session 1 -----------
delete from HumanResources.Department
where departmentid = 9
有人可以在这里分享一些亮点。我的所有概念似乎都破灭了。
答案 0 :(得分:0)
该表有departmentid,name,groupname,modifieddate。
Departmentid具有聚簇索引,并且名称具有非聚簇索引和其他列 - groupname和modifieddate包含在列中。发生了什么。
在会话1中选择查询将s锁定在非聚集索引上。
会话2将x锁定置于聚集索引上的departmentid = 9。
现在更改聚簇索引将更新非聚簇索引,因此会话2尝试将X锁定置于非聚簇索引,但被会话1的S锁定阻止。
会话1尝试通过在聚集索引上放置由会话2的X锁定阻止的x锁来删除同一行。因此陷入僵局。
我通过在会话1中使用select语句(index = Clusteredindexname)提示来解决它:
------Session 1----------
set transaction isolation level repeatable read
begin transaction
select * from HumanResources.Department with (index = Clusteredindexname)