Jules
Jules

Reputation: 4339

How to interpret a t-sql deadlock trace

I'm trying to sort out a deadlock by looking at the t-sql trace but I'm struggling to understand the information. I have a summary of the info here and then the full deadlock trace at the end of the post:

The first lock is on a table called dbo.RetailVoucher
The second lock is on a table called ooc.PlannedUniversalVoucher

The 1st stored procedure reads the following tables:
dbo.RetailVoucher, ooc.PlannedOrderItem and ooc.PlannedOrder.

The 2nd stored procedure reads the following tables:
ooc.PlannedBatch & ooc.PlannedUniversalVoucher

Now, for the procedures to be waiting for each other, I thought they would both have to be reading the same table at some point. I obviously don't understand how to interpret the trace. Do I need to hunt down the source of the locks on dbo.RetailerVoucher and ooc.PlannedUniversalVoucher in other procedures?

Thanks.

Here's the full trace:

<deadlock-list>
 <deadlock victim="process894748">
  <process-list>
   <process id="process894748" taskpriority="0" logused="3064" waitresource="KEY: 8:72057594084655104 (845afc30a382)" waittime="944" ownerId="12987790066" transactionname="user_transaction" lasttranstarted="2014-04-10T19:07:02.250" XDES="0x803d53c0" lockMode="S" schedulerid="3" kpid="14356" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="3" lastbatchstarted="2014-04-10T19:07:02.287" lastbatchcompleted="2014-04-10T19:07:02.287" clientapp=".Net SqlClient Data Provider" hostname="ID13115" hostpid="4872" loginname="UVUser" isolationlevel="read committed (2)" xactid="12987790066" currentdb="8" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
    <executionStack>
     <frame procname="UVSystem.ooc.PlannedPacketPreserveEVouchers" line="144" stmtstart="12286" stmtend="13618" sqlhandle="0x0300080039a18c7fa2ed9800dda200000100000000000000">
update dbo.RetailVoucher
            set QuantityInStock -= rvsum.QuantitySum
            from dbo.RetailVoucher urv
            join (
                select oib.id, SUM(oib.Quantity) as QuantitySum
                from (
                    select coalesce(rv.RelatedVoucherId, rv.Id) id, oi.Quantity
                    from 
                        ooc.PlannedOrderItem oi 
                        join ooc.PlannedOrder po on oi.PlannedOrderId = po.Id
                        join RetailVoucher rv on oi.RetailVoucherId = rv.Id
                    where po.PlannedPacketId = @PlannedPacketId
                        and oi.PartnerId is null
                        and oi.OnDmenadServiceId is null
                        and rv.VoucherTypeId = 1
                ) oib
                group by oib.Id
            ) rvsum
            on urv.Id = rvsum.id;

         </frame>
    </executionStack>
    <inputbuf>
Proc [Database Id = 8 Object Id = 2139922745]    </inputbuf>
   </process>
   <process id="processd0db8088" taskpriority="0" logused="10716" waitresource="PAGE: 8:1:778990" waittime="1078" ownerId="12987783115" transactionname="user_transaction" lasttranstarted="2014-04-10T19:07:01.473" XDES="0x144975950" lockMode="S" schedulerid="7" kpid="11172" status="suspended" spid="61" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2014-04-10T19:07:01.473" lastbatchcompleted="2014-04-10T19:07:01.473" clientapp=".Net SqlClient Data Provider" hostname="ID13115" hostpid="12168" loginname="UVUser" isolationlevel="read committed (2)" xactid="12987783115" currentdb="8" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
    <executionStack>
     <frame procname="UVSystem.ooc.OfflineOrdersImportPacket" line="294" stmtstart="23548" stmtend="24026" sqlhandle="0x030008006d6796551b829700dda200000100000000000000">
update ooc.PlannedBatch 
    set 
        IsCompleted = @True
    from ooc.PlannedBatch pb
        join ooc.PlannedUniversalVoucher puv on puv.PlannedBatchId = pb.Id
        left outer join @DuplicatedVouchers dv on dv.Id = puv.Id
    where dv.Id is null;     </frame>
    </executionStack>
    <inputbuf>
Proc [Database Id = 8 Object Id = 1435920237]    </inputbuf>
   </process>
  </process-list>
  <resource-list>
   <keylock hobtid="72057594084655104" dbid="8" objectname="UVSystem.dbo.RetailVoucher" indexname="PK_RetailVoucher" id="lock10ccbd180" mode="X" associatedObjectId="72057594084655104">
    <owner-list>
     <owner id="processd0db8088" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="process894748" mode="S" requestType="wait"/>
    </waiter-list>
   </keylock>
   <pagelock fileid="1" pageid="778990" dbid="8" objectname="UVSystem.ooc.PlannedUniversalVoucher" id="lock15ba81480" mode="IX" associatedObjectId="72057594113425408">
    <owner-list>
     <owner id="process894748" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="processd0db8088" mode="S" requestType="wait"/>
    </waiter-list>
   </pagelock>
  </resource-list>
 </deadlock>
</deadlock-list>

Upvotes: 1

Views: 950

Answers (1)

dean
dean

Reputation: 10098

Let me try.

You have tho processes, processd0db8088 and process894748. From the execution stack you can see that the process894748 was executing PlannedPacketPreserveEVouchers, and processd0db8088 is executing OfflineOrdersImportPacket. You can see the queries in question for both processes there as well.

From resource list you can find out the resorces on which these two processes were deadlocked. First one is a particular index row in PK_RetailVoucher index on RetailVoucher table: processd0db8088 locked it exclusively and the process process894748 is waiting to gain shared lock on it. The other resource is a data page 778990 which belongs to PlannedUniversalVoucher table, held by process process894748 while processd0db8088 is waiting to gain read access to it.

The locks could have been taken anywhere from start of transaction. The queries shown here in the execution stack are the queries that were waiting on the resources, not the ones that taken the locks. Inspect the whole execution trace to find out where the locks were actually taken.

The standard advices apply: shorten transactions, access the tables in order, index appropriatelly.

Upvotes: 5

Related Questions