Comment les blocages sont-ils détectés et signalés dans un SGBDR?

8

On m'a posé cette question de type essai lors d'une entrevue, mais je n'ai pas obtenu le poste. La question complète était la suivante:

Comment les blocages sont-ils détectés et signalés dans un SGBDR? Quels sont les propriétaires de transactions et les développeurs d'applications chargés d'assurer à la fois les scénarios de détection et de prévention?

Shadowcaz
la source

Réponses:

13

Dans SQL Server, il existe un thread distinct qui périodiquement (5 secondes par défaut, intervalle inférieur si un blocage vient d'être détecté) vérifie une liste d'attente pour tous les cycles. C'est-à-dire qu'il identifie la ressource qu'un thread attend, puis il trouve le propriétaire de cette ressource et recherche récursivement quelle ressource ce thread attend à son tour, identifiant ainsi les threads qui attendent les uns les autres.

Si un blocage est trouvé, une victime est choisie pour être tuée en utilisant cet algorithme:

  1. Identifiez les threads qui ne peuvent pas être supprimés (par exemple, un thread qui annule une transaction est impossible à tuer).
  2. Trouvez le thread avec la priorité de blocage la plus faible.
  3. Choisissez celui qui est le moins cher à annuler, c'est-à-dire celui qui a fait le moins de travail jusqu'à présent.

Vous pouvez trouver plus d'informations sur la détection de blocage des serveurs SQL ici: http://msdn.microsoft.com/en-us/library/ms178104.aspx



Le propriétaire de la transaction / développeur d'application est responsable de minimiser les risques de blocage et de faire qu'ils devraient:

  1. Assurez-vous de garder les transactions aussi courtes que possible. Par exemple, n'affichez pas de formulaire de connexion après avoir démarré une transaction et attendez l'entrée de l'utilisateur, rassemblez plutôt toutes les informations dont vous avez besoin, puis exécutez la transaction.
  2. Utilisez le niveau d'isolement le plus bas possible, par exemple, ne définissez pas sérialisable lorsque vous souhaitez simplement afficher temporairement certaines valeurs à l'utilisateur. Veuillez noter que la définition d'un niveau d'isolement correct est une science en soi et hors de portée dans cette réponse.
  3. Si vous êtes victime d'un blocage, c'est-à-dire que vous obtenez l'erreur # 1205, réexécutez votre transaction de manière transparente pour votre utilisateur. Étant donné que l'autre transaction, concurrente, a maintenant, espérons-le, acquis les ressources qu'elle attendait et se termine, il est peu probable que vous rencontriez à nouveau le même blocage.
Andreas Ågren
la source
4. Acquérir des ressources et exécuter des modèles de mise à jour / suppression / insertion dans le même ordre de manière cohérente tout au long de l'application.
ErikE
3
@ErikE, il n'est souvent pas possible / faisable de "mettre à jour / supprimer / insérer des motifs dans le même ordre de manière cohérente dans l'application", bien que ce conseil douteux soit très populaire sur le Web. Détails ici: sqlblog.com/blogs/alexander_kuznetsov/archive/2010/01/15/…
AK
1
Bons points. Mais je pense toujours que l'effort en vaut la peine, tant que l'on ne se fait aucune illusion qu'il sera toujours possible ou qu'il résoudra toujours le problème. La chose parent / enfant est intéressante, que diriez-vous des suppressions en cascade ou de l'acquisition d'un verrou de mise à jour sur les lignes parent en premier? Et si vous fusionnez sans MERGE, pourquoi ne pas être cohérent? Je supprime-> mise à jour-> insère personnellement.
ErikE
1
@AlexKuznetsov: Ce n'est pas une balle de solveur mais ne doit pas être ignorée. J'ai réduit (éliminé) DEADLOCKS cette façon si: via l' analyse statique de code fréquemment courir qui n'IMPASSE tous les jours ou 7. Je vous suggère de « l' optimisation prématurée » applique etc
GBN
Je ne suis pas d'accord avec la recommandation numéro 3. Lorsque nous réessayons après des blocages, nous sommes très susceptibles d'écraser les modifications d'autres processus. Nous devons être conscients que très probablement quelqu'un d'autre a modifié les données que nous avions l'intention de modifier. Surtout si tous les lecteurs s'exécutent sous l'isolement de l'instantané, les lecteurs ne peuvent pas être impliqués dans des blocages, ce qui signifie que toutes les parties impliquées dans un blocage sont des écrivains, ont modifié ou tenté de modifier les mêmes données. Si nous interceptons l'exception et réessayons automatiquement, nous pouvons remplacer les modifications de quelqu'un d'autre. C'est ce qu'on appelle des mises à jour perdues, et c'est généralement faux.
AK