2009-02-10 7 views
3

L'instruction SQL suivante génère parfois des blocages dans mon mssqlserver 2000 serveurDeadlock dans suppression de sélection

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) 

Pour une raison quelconque, la suppression obtient un statut de blocage et ne se termine pas (?) Le seul autre processus Ce que je trouve bloqué par cela, c'est un plan de maintenance qui se déroule le week-end pour recréer les indices, donc je n'ai aucune idée de ce qui pourrait générer le problème.

Ce sont les verrous générés par la suppression ...

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

Quelqu'un a des conseils sur la façon d'obtenir à la racine du problème? Je soupçonne que la table tb_intervaloServico est la racine du blocage car elle est appelée dans la suppression et dans la sélection, mais je ne peux pas reproduire le comportement.

Répondre

1

Vous devez activer certains indicateurs de suivi sur votre base de données afin que vous obtenez une impression dans votre journal qui explique la chaîne de blocage. Essayez de démarrer le serveur SQL avec les indicateurs de trace 1204, 1205 et 1206. Ensuite, publiez la chaîne de blocage.

Vous pouvez essayer l'escalade des verrous dans votre sql, il est possible cela réparer mais sans la chaîne impression qu'il soit impossible de dire

Alors peut-être cela vous aidera:

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

ressemble à votre requête est autobloquants. Vous voudrez peut-être lire this newsgroup thread (spécialement l'affichage de Santeri Voutilainen) à propos de ce problème.

C'est probablement un problème avec SP4. Vous pouvez essayer de réduire le parallélisme de la requête en réduisant le nombre de processeurs utilisés pour l'exécution de la requête. Pour cela, vous pouvez utiliser l'indicateur de requête OPTION (MAXDOP n) où n est le nombre de threads parallèles. Définir n = 0 signifie utiliser tous les processeurs disponibles.

Sinon, vous pouvez également définir l'option de manière globale: dans Enterprise Manager sous « Propriétés - processeur - Parallélisme » cliquez sur le bouton radio à côté de « Utiliser » et sélectionnez 1.

0

Votre suppression d'une table de votre joindre à, tb_intervaloServico. Vider votre sous-requête dans une table temporaire et utiliser la table temporaire dans votre suppression.

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

il n'y a pas besoin d'utiliser la table temporaire, vous pouvez escalader les verrous sur la sélection avec un soupçon –

1

essayez de changer votre requête:

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) 

ou peut-être:

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 

Vous pouvez tester ces requêtes supprimer avant d'utiliser select * au lieu de supprimer