Le blocage est un phénomène normal dans toute base de données relationnelle reposant sur le verrouillage : une session détient un verrou tandis qu'une autre attend de l'acquérir. Cela devient problématique lorsque l'attente est suffisamment longue pour ralentir votre application. Une cause fréquente réside dans une application qui lit ou écrit fréquemment dans la même table ou ressource, ce qui peut générer un grand nombre de requêtes concurrentes et dégrader les performances de l'application. Cette rubrique vous explique comment identifier la session à l'origine du blocage et comment y remédier.
Identifier la session bloquante
Utilisez l'une des méthodes suivantes pour trouver la session détenant les verrous.
Méthode 1 : Interroger sys.sysprocesses
Exécutez l'instruction suivante pour interroger sys.sysprocesses à intervalles réguliers :
WHILE 1 = 1
BEGIN
SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0;
WAITFOR DELAY '00:00:01';
END;
La valeur deWAITFOR DELAYcontrôle l'intervalle d'interrogation. L'exemple utilise une seconde (00:00:01). Ajustez cette valeur selon vos besoins.
La figure suivante présente un exemple de sortie.

Colonnes clés dans la sortie :
blocked: ID de la session bloquante — la session détenant le verrou qui empêche les autres de progresser.waitresource: Ressource que la session bloquée attend d'acquérir.
Pour la liste complète des colonnes, consultez sys.sysprocesses (Transact-SQL).
Méthode 2 : Interroger sys.dm_tran_locks et sys.dm_os_waiting_tasks
Pour obtenir plus de détails, notamment sur les objets et instructions impliqués, exécutez l'instruction suivante afin de joindre sys.dm_tran_locks à sys.dm_os_waiting_tasks :
WHILE 1 = 1
Begin
SELECT db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingText,
tl.request_mode
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
WAITFOR DELAY '00:00:01';
END;
La figure suivante présente un exemple de sortie.

La sortie inclut les colonnes suivantes :
| Colonne | Description |
|---|---|
DBName |
Nom de la base de données. |
request_session_id |
ID de la session bloquée. |
blocking_session_id |
ID de la session bloquante. |
BlockedObjectName |
Objets gérés par la session bloquée. |
resource_type |
Type de ressource que la session attend d'acquérir. |
RequestingText |
Instruction en cours d'exécution dans la session bloquée. |
BlockingText |
Instruction en cours d'exécution dans la session bloquante. |
request_mode |
Mode de verrouillage demandé par la session bloquée. |
Résoudre le problème de blocage
Après avoir identifié la session bloquante et les instructions impliquées, prenez une ou plusieurs des mesures suivantes.
Terminer la session bloquante
Exécutez KILL <session_id> pour mettre fin à la session détenant le verrou, ce qui débloque immédiatement les sessions en attente. Utilisez cette mesure en cas d'urgence et analysez la cause racine par la suite pour éviter une récurrence.
Valider les transactions ouvertes de longue durée
Vérifiez s'il existe des transactions ouvertes depuis longtemps sans avoir été validées. Les transactions ouvertes conservent leurs verrous jusqu'à leur achèvement. Validez ou annulez rapidement toutes les transactions de ce type.
Utiliser WITH (NOLOCK) pour les requêtes en lecture seule (avec prudence)
Si une requête SELECT est bloquée en raison de verrous partagés et que votre application peut tolérer des lectures sales, utilisez l'indicateur de requête WITH (NOLOCK) :
SELECT * FROM table WITH (NOLOCK);
WITH (NOLOCK) ignore l'acquisition de verrous partagés, de sorte que la requête n'est jamais bloquée par les opérations d'écriture. Toutefois, elle risque de lire des données non validées qui seront ultérieurement annulées. N'utilisez cette option que si votre application peut gérer des lectures incohérentes.
Accéder aux ressources dans un ordre cohérent
Si plusieurs transactions accèdent au même ensemble de tables dans des séquences différentes, elles peuvent former des chaînes de blocage ou des interblocages. Passez en revue la logique de votre application et assurez-vous que toutes les transactions acquièrent les verrous sur les ressources partagées dans le même ordre.
Étapes suivantes
Pour connaître les étapes permettant de résoudre les blocages dans les situations d'urgence, consultez Résoudre les problèmes de blocage sur une instance ApsaraDB RDS for SQL Server.
Pour détecter les blocages avant qu'ils n'affectent votre application, configurez les métriques de performance et les règles d'alerte dans la console ApsaraDB RDS. Consultez Surveillance et alertes.
Pour les stratégies d'optimisation des index, des requêtes et du stockage, consultez Optimisation et diagnostic des performances.