The puzzle of U locks in deadlock graphs
May 12th, 2010In a stackoverflow.com question the user has asked how come a SELECT statement could own a U mode lock?
The deadlock indeed suggests that the deadlock victim, a SELECT statement, is owning an U lock on the PK_B index. Why would a SELECT own an U lock? The query had no table hints and was a standalone query, not part of a multi-statement transaction that could had aquired the U lock in previous staements.
Turns out that the SELECT was actually not owning any U lock. The deadlock graph files (the *.xdl files) are in fact XML files and they can be opened as XML and inspected, for a little more detail than the visual deadlock graph visualizer permits. Here is the actual resource list in the deadlock XML:
<resource-list> <keylock hobtid="72057594052411392" dbid="10" objectname="A" indexname="PK_A" id="lock17ed4040" mode="X" associatedObjectId="72057594052411392"> <owner-list> <owner id="process4f5d000" mode="X"/> </owner-list> <waiter-list> <waiter id="processfa3c8e0" mode="S" requestType="wait"/> </waiter-list> </keylock> <keylock hobtid="72057594051166208" dbid="10" objectname="B" indexname="PK_B" id="lock22ea3940" mode="U" associatedObjectId="72057594051166208"> <owner-list> <owner id="processfa3c8e0" mode="S"/> </owner-list> <waiter-list> <waiter id="process4f5d000" mode="X" requestType="convert"/> </waiter-list> </keylock> </resource-list>
As you can see, the resource lock22ea3940 is owned by the process processfa3c8e0 (the SELECT) indeed, but is owned in S mode. The process process4f5d000 (the UPDATE) is requesting this resource for a convert from U to X mode. So the true deadlock is like this:
- SELECT owns a lock on the row in PK_B in S mode
- SELECT wants a lock on the row in PK_A in S mode
- UPDATE owns a lock on the row in PK_A in X mode
- UPDATE also owns a U lock on the PK_B row. (S and U modes are compatible)
- UPDATE is requesting a convert of the U lock it has on the row on PK_B to X mode
As you can see, there is no mysterious U lock owned by the SELECT. There is an U lock on the row in PK_B, but is owned by the UPDATE, which is requesting a convert to X for it. The fact that the resource is showned in the deadlock graph viewer in SSMS as being ‘Owner mode: U’ and pointing to the SELECT is simply an artifact of how SSMS displays the deadlock graph.
The lesson to take home is that the visual graphic deadlock graph display is usefull only to have a cursory glance at the deadlock cycle. The true meat and potatoes are in the XML, which has a lot more information. Not to mention that the information in the XML is actually correct, which helps investigation…