我们的应用程序存在死锁问题。 最近几天,我阅读了很多关于阻塞、锁定和死锁的内容,以便理解问题并解决它。
现在,当我读取有关死锁的错误日志信息时,我无法理解这种情况是如何存在的。 看看这个(我已经将表名更改为OurTable,但日志消息中重要的是这个表):
spid 155 在等待 OurTable 上的共享表锁 (spid 124 持有冲突的X锁)
spid 153 在等待 OurTable 上的共享表锁 (spid 124 持有冲突的X锁)
spid 124 在等待 OurTable 上的排他表锁 (spid 155 持有冲突的IS锁)
我的问题是为什么会发生这种情况。两个会话同时持有整个表的一个锁。我以为通常死锁是当两个或更多会话持有不同资源的锁并互相等待。但这里的锁是在相同的资源上。它不是索引上的锁,而是表上的锁。我们的应用程序中经常出现这种错误,某个锁必须是第一个被请求的,为什么如果已经有一个锁在整个表上,第二个锁会被接受?
有人能够给出提示有什么问题或者有没有经历过类似的死锁情况吗?
现在,当我读取有关死锁的错误日志信息时,我无法理解这种情况是如何存在的。 看看这个(我已经将表名更改为OurTable,但日志消息中重要的是这个表):
deadlock-list
deadlock victim=process1e2ac02c8
process-list
process id=process1e2ac02c8 taskpriority=0 logused=0 waitresource=OBJECT: 11:290100074:0 waittime=704 ownerId=3144354890 transactionname=SELECT lasttranstarted=2011-12-01T14:43:20.577 XDES=0x80017920 lockMode=S schedulerid=6 kpid=7508 status=suspended spid=155 sbid=0 ecid=0 priority=0 trancount=0 lastbatchstarted=2011-12-01T14:43:20.577 lastbatchcompleted=2011-12-01T14:43:20.577 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=5856 loginname=2Ezy isolationlevel=read committed (2) xactid=3144354890 currentdb=11 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
executionStack
frame procname=.dbo.RetrieveSomething line=23 stmtstart=1398 stmtend=3724 sqlhandle=0x03000b0030d42d645a63e6006a9f00000100000000000000
select
Col1
,Col2
,(
SELECT TOP(1)
Col1
FROM
OurTable2 AS C
JOIN OurTable AS ETC ON C.Id = ETC.FKId
AND E.Id = C.FKId
ORDER BY ETC.Col2
) AS Col3
from OurTable3 AS E
process id=process2df4894c8 taskpriority=0 logused=0 waitresource=OBJECT: 11:290100074:0 waittime=9713 ownerId=3144330250 transactionname=INSERT EXEC lasttranstarted=2011-12-01T14:43:11.573 XDES=0x370764930 lockMode=S schedulerid=13 kpid=4408 status=suspended spid=153 sbid=0 ecid=0 priority=0 trancount=1 lastbatchstarted=2011-12-01T14:43:11.573 lastbatchcompleted=2011-12-01T14:43:11.573 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=5856 loginname=2Ezy isolationlevel=read committed (2) xactid=3144330250 currentdb=11 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
executionStack
frame procname=adhoc line=1 sqlhandle=0x02000000ba6cb42612240bdb19f7303e279a714276c04344
select
Col1
, Col2
, Col3
, ISNULL(
(select top(1)
E_SUB.Col1 + ' ' + E_SUB.Col2
from OurTable3 as E_SUB
inner join OurTable2 as C on E_SUB.Id = C.FKId
inner join OurTable as ETC on C.Id = ETC.FKId
as Col3
from OurTable4
inner join dbo.OurTable as ETC on Id = ETC.FKId
process id=process8674c8 taskpriority=0 logused=0 waitresource=OBJECT: 11:290100074:5 waittime=338 ownerId=3143936820 transactionname=INSERT lasttranstarted=2011-12-01T14:38:24.423 XDES=0x1ecd229f0 lockMode=X schedulerid=7 kpid=12092 status=suspended spid=124 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2011-12-01T14:38:23.027 lastbatchcompleted=2011-12-01T14:38:23.013 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=5856 loginname=2Ezy isolationlevel=read committed (2) xactid=3143936820 currentdb=11 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
executionStack
frame procname=.dbo.UpsertSomething line=332 stmtstart=27712 stmtend=31692 sqlhandle=0x03000b00bbf2a93c0f63a700759f00000100000000000000
insert into dbo.OurTable
(
Col1
,Col2
,Col3
)
values
(
@Col1
,@Col2
,@Col3
)
resource-list
objectlock lockPartition=0 objid=290100074 subresource=FULL dbid=11 objectname=dbo.OurTable id=lock16a1fde80 mode=X associatedObjectId=290100074
owner-list
waiter-list
waiter id=process1e2ac02c8 mode=S requestType=wait
objectlock lockPartition=0 objid=290100074 subresource=FULL dbid=11 objectname=dbo.OurTable id=lock16a1fde80 mode=X associatedObjectId=290100074
owner-list
owner id=process8674c8 mode=X
waiter-list
waiter id=process2df4894c8 mode=S requestType=wait
objectlock lockPartition=5 objid=290100074 subresource=FULL dbid=11 objectname=dbo.OurTable id=lock212f0f300 mode=IS associatedObjectId=290100074
owner-list
owner id=process1e2ac02c8 mode=IS
waiter-list
waiter id=process8674c8 mode=X requestType=wait
我理解的是:spid 155 在等待 OurTable 上的共享表锁 (spid 124 持有冲突的X锁)
spid 153 在等待 OurTable 上的共享表锁 (spid 124 持有冲突的X锁)
spid 124 在等待 OurTable 上的排他表锁 (spid 155 持有冲突的IS锁)
我的问题是为什么会发生这种情况。两个会话同时持有整个表的一个锁。我以为通常死锁是当两个或更多会话持有不同资源的锁并互相等待。但这里的锁是在相同的资源上。它不是索引上的锁,而是表上的锁。我们的应用程序中经常出现这种错误,某个锁必须是第一个被请求的,为什么如果已经有一个锁在整个表上,第二个锁会被接受?
有人能够给出提示有什么问题或者有没有经历过类似的死锁情况吗?
11:290100074:5
与11:290100074:0
。最终数字应该代表sys.indexes
中的indexId
根据此处。另外,为什么你的第二个事务被命名为INSERT EXEC
,当它显然只执行了一个SELECT
?在同一事务中之前是否有其他代码运行? - Martin Smith