我已经在Table SPIDtable中捕获了spid,blockedByspid列 价值观是这样的 这里,死锁循环是116-> 243-> 248-> 116 这张表中有很多这样的死锁。
spid blockedBy
116 208
116 243
243 248
248 116
我写过CTE查询打印出所有这样的周期
这是找到一些周期,但是在最多100次递归后停止,是否有更好的方法
;WITH cte( spid, blockedBy, isCycle)
as
(
select spid, blockedBy , 0 FROM SPIDTable
where blockedby <>0
union all
select S.spid , S.blockedBy, ( case when CTE.blockedBy = S.spid then 1 else 0 end) as cycle from CTE
inner join SPIDtable S
on S.blockedBy = CTE.spid
)
select * from CTE where isCycle =1
答案 0 :(得分:2)
根据定义,死锁图将至少有一次循环。因此,如果您只是在blocker.spid = blocked.blockedBy上运行查询,除非您有终止子句,否则将永远迭代。这就是我想出的:
with SPIDTable as (
select * from (values
(116, 208),
(116, 243),
(243, 248),
(248, 116)
) as x(spid, blockedBy)
)
, cte as (
select spid
, blockedBy
, 0 as isCycle, spid as [starter]
, cast(spid as nvarchar(max)) as [chain]
, 1 as [level]
FROM SPIDTable
where blockedby <> 0
union all
select S.spid , S.blockedBy
, case when CTE.starter = S.spid then 1 else 0 end as cycle
, cte.starter as [starter]
, cte.chain + '/' + cast(s.spid as nvarchar(max)) as [chain]
, cte.[level] + 1 as [level]
from CTE
inner join SPIDtable S
on S.blockedBy = CTE.spid
where s.spid <> cte.starter
)
select * from CTE
order by [level]
请注意,在此示例中,所有“3级”行代表相同的循环(即116→248→243→116)。但在所有情况下,具有最高级别的行将是完整的死锁循环(其中最后一个(省略的)spid将只是链中的第一个spid。)