Interblocage

Un interblocage se produit lorsque deux ou plusieurs tâches se bloquent mutuellement parce que chacune d'elles détient un verrou sur une ressource que les autres tâches essaient de verrouiller. Par exemple :

  • La transaction A obtient un verrou partagé sur la ligne 1.

  • La transaction B obtient un verrou partagé sur la ligne 2.

  • La transaction A demande un verrou exclusif sur la ligne 2, mais elle est bloquée jusqu'à la fin de la transaction B qui libérera le verrou partagé sur la ligne 2.

  • La transaction B demande un verrou exclusif sur la ligne 1, mais elle est bloquée jusqu'à la fin de la transaction A qui libérera le verrou partagé sur la ligne 1.

La transaction A ne peut pas se terminer tant que la transaction B n'est pas terminée, mais la transaction B est bloquée par la transaction A. Il s'agit d'une interdépendance sans fin : La transaction A est dépendante de la transaction B, mais celle-ci ne peut pas s'exécuter car elle est dépendante de la transaction A.

Les deux transactions en interblocage attendent indéfiniment que la situation soit débloquée par un processus externe. Le processus de surveillance des blocages du moteur de base de données SQL Server Microsoft vérifie périodiquement l'existence de tâches en interblocage. S'il détecte une situation d'interdépendance sans fin, il désigne une des tâches comme victime et met fin à sa transaction avec un message d'erreur. Cela permet à l'autre tâche de terminer sa transaction. L'application qui exécutait la transaction abandonnée peut effectuer une nouvelle tentative qui réussit en général une fois que l'autre transaction est terminée.

Le respect de certaines conventions lors du codage des applications réduit les risques d'interblocage. Pour plus d'informations, consultez Réduction des blocages.

L'interblocage est souvent confondu avec le blocage ordinaire. Lorsqu'une transaction demande un verrou sur une ressource verrouillée par une autre transaction, elle attend que le verrou soit libéré. Par défaut, les transactions SQL Server n'ont pas de délai d'expiration, à moins que LOCK_TIMEOUT ne soit activé. La transaction qui demande le verrou est bloquée, mais pas indéfiniment puisqu'elle n'a rien fait pour bloquer la transaction détenant le verrou. La transaction qui détient le verrou va finir par se terminer et libérer le verrou ; l'autre transaction pourra alors obtenir son verrou et s'exécuter normalement.

Les interblocages sont parfois appelés « étreintes fatales ».

Une situation d'interblocage peut se produire sur tout système multithread, pas uniquement sur les systèmes de gestion de bases de données relationnelles. Elle peut également concerner des ressources autres que les verrous sur les objets de base de données. Par exemple, une thread dans un système multithread peut acquérir une ou plusieurs ressources (par exemple, des blocs de mémoire). Si la ressource acquise appartient actuellement à une autre thread, la première thread devra éventuellement attendre que la thread propriétaire libère la ressource cible. La thread en attente a une dépendance sur la thread propriétaire de cette ressource particulière. Dans une instance du moteur de base de données, les sessions peuvent se bloquer mutuellement lors de l'acquisition de ressources autres que des objets de base de données, notamment des blocs de mémoire ou des threads.

Diagramme illustrant l'interblocage des transactions

Dans l'illustration, la transaction T1 est dépendante de la transaction T2 pour la ressource de verrouillage de table Part. De même, la transaction T2 est dépendante de T1 pour la ressource de verrouillage de table Supplier. Comme ces dépendances forment un cycle, il y a interblocage entre les transactions T1 et T2.

Des interblocages peuvent également se produire lorsqu'une table est partitionnée et que le paramètre LOCK_ESCALATION de TABLE ALTER a la valeur AUTO. Lorsque LOCK_ESCALATION a la valeur AUTO, la concurrence augmente en permettant au Moteur de base de données de verrouiller des partitions de table au niveau du HoBT plutôt qu'au niveau de la TABLE. Toutefois, lorsque des transactions distinctes maintiennent des verrous de partition dans une table et souhaitent un verrou sur l'autre partition de transactions, cela provoque un interblocage. Ce type d'interblocage peut être évité en affectant à LOCK_ESCALATION la valeur TABLE, bien que ce paramètre réduise la concurrence en forçant les mises à jour volumineuses d'une partition à attendre un verrou de table.