Jul*_*les 1 t-sql database sql-server deadlock ssms
我试图通过查看 t-sql 跟踪来解决死锁,但我很难理解这些信息。我在这里总结了信息,然后在帖子末尾提供了完整的死锁跟踪:
第一个锁位于名为 dbo.RetailVoucher 的表上
第二个锁位于名为 ooc.PlannedUniversalVoucher 的表上
第一个存储过程读取下表:
dbo.RetailVoucher、ooc.PlannedOrderItem 和 ooc.PlannedOrder。
第二个存储过程读取下表:
ooc.PlannedBatch & ooc.PlannedUniversalVoucher
现在,为了使程序相互等待,我认为它们都必须在某个时刻读取同一个表。我显然不明白如何解释该痕迹。我是否需要在其他程序中追查 dbo.RetailerVoucher 和 ooc.PlannedUniversalVoucher 上的锁定来源?
谢谢。
这是完整的跟踪:
<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>
Run Code Online (Sandbox Code Playgroud)
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.
标准建议适用:缩短事务、按顺序访问表、适当索引。
归档时间: |
|
查看次数: |
801 次 |
最近记录: |