代码之家  ›  专栏  ›  技术社区  ›  bastos.sergio

delete-select中的死锁

  •  3
  • bastos.sergio  · 技术社区  · 17 年前

    以下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中被调用,但我无法重现这种行为。

    5 回复  |  直到 10 年前
        1
  •  1
  •   Sam Saffron James Allen    17 年前

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

    尝试使用跟踪标志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)
    
        2
  •  1
  •   MicSim    17 年前

    看起来您的查询是自锁的。你可能想读书 this newsgroup thread

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

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

        3
  •  1
  •   kristof    17 年前

    尝试将查询更改为:

    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
    

    您可以在删除之前使用 而不是 删去

        4
  •  0
  •   John Sansom    17 年前

    下面的文章将指导您如何解决SQLServer2000中的死锁问题。

    http://msdn.microsoft.com/en-us/library/aa937573(SQL.80).aspx

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

        5
  •  0
  •   jason saldo    17 年前

    从表中删除要加入的对象,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
    )