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

回答

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) 
1

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

这可能是SP4的问题。您可以尝试通过减少用于查询执行的处理器数量来减少查询并行性。为此,您可以使用查询提示OPTION(MAXDOP n),其中n是并行线程的数量。设置n = 0意味着使用所有可用的处理器。在企业管理器下“ - 处理器 - 属性并行”点击旁边的“使用”单选按钮,然后从你加入到一个表中选择1

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 
) 
+0

有没有需要使用临时表,你可以升级的选择锁有提示之前删除 – 2009-02-11 10:17:40

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 *的代替删除