3

以下 SQL 语句偶尔会在我的 mssqlserver 2000 服务器中产生死锁

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 是阻塞的根,因为它在删除和选择中被调用,但我无法重现该行为。

4

5 回答 5

1

看起来您的查询是自锁的。您可能想阅读有关此问题的新闻组主题(特别是 Santeri Voutilainen 的帖子)。

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

或者,您也可以全局设置该选项:在 Enterprise Manager 中的“Properties - Processor - Parallelism”下,单击“Use”旁边的单选按钮并选择 1。

于 2009-02-10T18:50:10.467 回答
1

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

尝试使用跟踪标志 1204、1205 和 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)
于 2009-02-11T10:24:05.213 回答
1

尝试将您的查询更改为:

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测试这些查询

于 2009-02-11T10:42:00.117 回答
0

以下文章将指导您了解如何解决 SQL Server 2000 中的死锁。

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

如果您需要具体帮助,请告诉我。

干杯,约翰

于 2009-02-10T17:22:18.477 回答
0

您从加入的表中删除,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
)
于 2009-02-10T19:56:40.027 回答