Sql server delete-select中的死锁

Sql server delete-select中的死锁,sql-server,deadlock,Sql Server,Deadlock,以下SQL语句偶尔会在我的MSSQLServer2000服务器中生成死锁 delete from tb_intervaloServico where idFeriado in ( select ints.idIntervalo from tb_periodicidadeServico ps, tb_intervaloServico ints where ints.idPeriodicidadeServico=ps.idPeriodicidadeServico

以下SQL语句偶尔会在我的MSSQLServer2000服务器中生成死锁

delete from tb_intervaloServico 
where idFeriado in (
    select ints.idIntervalo 
    from tb_periodicidadeServico ps, tb_intervaloServico ints 
    where ints.idPeriodicidadeServico=ps.idPeriodicidadeServico
    and idservicoContrato='7f20b4af-9076-48f9-a861-8b78273eadc3'
    and fromFixa=0)
出于某种原因,删除操作会处于阻塞状态,并且没有完成(?)我发现唯一被阻塞的另一个过程是在周末运行的维护计划,以重新创建索引,因此我不知道是什么导致了问题

这是删除生成的锁

Object                  Lock Type Mode Status Owner
tb_intervaloServico     TAB       IX   GRANT  Xact
tb_periodicidadeServico TAB       IS   GRANT  Xact

有人对如何找到问题的根源有什么建议吗?我怀疑tb_intervaloServico表是阻塞的根源,因为它在delete和select中被调用,但我无法重现这种行为。

下面的文章将指导您如何解决SQL Server 2000中的死锁问题

如果您需要特殊帮助,请告诉我


干杯,John看起来您的查询是自锁的。你可能想阅读(特别是Santeri Voutilainen的帖子)关于这个问题的文章

这可能是SP4的问题。您可以尝试通过减少用于查询执行的处理器数量来降低查询并行性。为此,可以使用查询提示选项(MAXDOP n),其中n是并行线程的数量。设置n=0意味着使用所有可用的处理器


或者,您也可以全局设置该选项:在Enterprise Manager中的“属性-处理器-并行性”下,单击“使用”旁边的单选按钮,然后选择1。

从加入到的表中删除,tb_intervaloServico。将子查询转储到临时表中,并在删除中使用临时表

select ints.idIntervalo into #deleteMeId
from tb_periodicidadeServico ps, tb_intervaloServico ints 
where ints.idPeriodicidadeServico=ps.idPeriodicidadeServico
and idservicoContrato='7f20b4af-9076-48f9-a861-8b78273eadc3'
and fromFixa=0)

delete from tb_intervaloServico 
where idFeriado in (
select * from #deleteMeId
)

您需要在数据库上启用一些跟踪标志,以便在日志中获得解释死锁链的打印输出

尝试使用跟踪标志12041205和1206启动SQL server。然后发布死锁链

您可以尝试升级sql中的锁,这可能会修复它,但如果没有链打印输出,则无法确定

因此,也许这将有助于:

delete from tb_intervaloServico 
where idFeriado in (
    select ints.idIntervalo 
    from tb_periodicidadeServico ps, tb_intervaloServico ints 
    with (updlock,serializable)
    where ints.idPeriodicidadeServico=ps.idPeriodicidadeServico
    and idservicoContrato='7f20b4af-9076-48f9-a861-8b78273eadc3'
    and fromFixa=0)

尝试将查询更改为:

delete tis
from 
    tb_intervaloServico tis
where tis.idFeriado in (
    select ints.idIntervalo 
    from tb_periodicidadeServico ps, tb_intervaloServico ints 
    where ints.idPeriodicidadeServico=ps.idPeriodicidadeServico
    and idservicoContrato='7f20b4af-9076-48f9-a861-8b78273eadc3'
    and fromFixa=0)
或者可能:

delete tis
from 
    tb_intervaloServico tis
    inner join tb_intervaloServico ints
        on tis.idFeriado = ints.idIntervalo
    inner join tb_periodicidadeServico ps
        on ints.idPeriodicidadeServico = ps.idPeriodicidadeServico
        and idservicoContrato='7f20b4af-9076-48f9-a861-8b78273eadc3' -- add the correct table prefix for idservicoContrato
        and fromFixa = 0 -- add the correct table prefix for fromFixa

您可以在删除之前使用select*测试这些查询,而不是delete

如果不需要使用临时表,您可以通过提示升级select上的锁