Reputation: 1304
This is a strange finding. I am doing select and delete on one session and delete on another session on the same row please see my code below. departmentid has clustered index.
------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
This is what should happen.
delete
statement and should put a [u]
lock on the row and then tries to convert the u
lock to X
lock which is blocked because of s
lock been held by session 1delete
statement tries to put X
lock but is blocked by the u
lock of session 2. Hence deadlock happens. However when I see the deadlock graph I get a different picture. Deadlock graph tells that session 1 grants S lock. Session 2 grants X lock(I have confusion here) how can x lock be granted on S lock. See the deadlock graph below :
<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>
I have another finding this is also very strange. If I change my select statement of session 1, that is I add where clause in it I do not get any deadlock. I only see session 2 been blocked and session 1 deletes the row with departmentid = 9. refer to my query below : -
------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
Can someone share some light here. All my concepts seem to be shattered here.
Upvotes: 0
Views: 366
Reputation: 1304
The table has departmentid, name, groupname,modifieddate.
Departmentid has clustered index and name has nonclustered index and other columns - groupname and modifieddate are included columns. This what happened.
select query in session 1 puts s lock on nonclustered index.
session 2 put x lock on departmentid = 9 on clustered index.
Now altering clustered index will update nonclustered index so session 2 tries to put X lock to nonclustered index but is blocked by S lock of session 1.
Session 1 tries to delete the same row by putting x lock which is blocked by X lock of session 2 on clustered index. Hence deadlock.
I resolved it by putting hint with (index = Clusteredindexname) with select statement in session 1 :
------Session 1----------
set transaction isolation level repeatable read
begin transaction
select * from HumanResources.Department with (index = Clusteredindexname)
Upvotes: 1