delete-select中的死锁

时间:2009-02-10 16:23:06

标签: sql-server deadlock

以下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)

由于某种原因,删除得到阻止状态并且没有完成(?)我发现阻止它的唯一其他进程是一个维护计划,它在周末运行以重新创建索引,所以我没有什么可能产生问题。

这是delete ...

生成的锁
Object                  Lock Type Mode Status Owner
tb_intervaloServico     TAB       IX   GRANT  Xact
tb_periodicidadeServico TAB       IS   GRANT  Xact

任何人都有关于如何找到问题根源的任何指示?我怀疑表tb_intervaloServico是阻塞的根,因为它在删除和select中被调用,但我无法重现该行为。

5 个答案:

答案 0 :(得分:1)

您的查询看起来像是自锁的。您可能想阅读this newsgroup thread(特别是Santeri Voutilainen的发布)关于此问题。

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

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

答案 1 :(得分: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)

答案 2 :(得分: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

您可以使用选择* 代替删除

在删除前测试这些查询

答案 3 :(得分:0)

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

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

如果您需要特殊帮助,请与我们联系。

干杯,约翰

答案 4 :(得分: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
)