Pratique SQL Server

Timeouts SQL Server : annulation et reprises fiables

Distinguez les délais de connexion, de commande et de verrouillage, puis concevez des reprises qui ne dupliquent pas les écritures incertaines.

Un timeout indique que l'appelant a épuisé son budget d'attente. Il ne dit pas à lui seul si la requête était lente, bloquée, annulée avant validation ou validée avant la perte de réponse. Réessayer immédiatement en supposant un échec transactionnel peut transformer un incident de latence en opérations métier dupliquées.

Identifier le délai réellement dépassé

Le délai de connexion concerne l'ouverture, avec le réseau, l'authentification ou l'obtention de ressources. Le délai de commande concerne l'exécution via le fournisseur client. SET LOCK_TIMEOUT limite l'attente de verrous dans SQL Server. Ces réglages couvrent des étapes différentes.

L'exemple modifie uniquement le budget d'attente des verrous de la session, puis rétablit sa valeur illimitée. Il ne limite pas la durée totale d'une requête.

SET LOCK_TIMEOUT 1500;
SELECT @@LOCK_TIMEOUT AS LockTimeoutMilliseconds;
SET LOCK_TIMEOUT -1;

SELECT XACT_STATE() AS TransactionState,
       @@TRANCOUNT AS TransactionCount;

Un dépassement de verrou produit une erreur SQL Server que l'application peut classer. Un délai de commande est généralement signalé par le pilote et entraîne une demande d'annulation. Conservez le fournisseur, les détails de l'erreur, la durée, un identifiant de corrélation et la présence éventuelle d'une transaction active. Le message générique du framework web ne suffit pas.

Séparez aussi la limite HTTP du budget de commande. Si la couche HTTP abandonne sans propager l'annulation, le traitement SQL peut continuer sans destinataire intéressé. Alignez les budgets en laissant du temps au nettoyage et à une réponse compréhensible.

Observer avant la disparition de la requête

Pendant l'incident, capturez attentes, blocages, durée et transactions ouvertes. Ces requêtes en lecture seule nécessitent les permissions de diagnostic adaptées à la version.

SELECT
    session_id, request_id, status, command,
    wait_type, wait_time, blocking_session_id,
    total_elapsed_time, cpu_time,
    reads, logical_reads, writes
FROM sys.dm_exec_requests
WHERE session_id <> @@SPID;

SELECT
    session_id, status, open_transaction_count,
    last_request_start_time, last_request_end_time,
    host_name, program_name
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
  AND open_transaction_count > 0;

Une requête bloquée par un verrou ne se traite pas comme une requête consommant du CPU ou attendant de la mémoire. La seconde requête peut montrer une session inactive avec transaction ouverte, absente de la liste des requêtes actives. Les noms de machine et de programme sont des étiquettes fournies par le client, pas des identités de sécurité fiables.

Pour les incidents récurrents, rapprochez les horodatages applicatifs d'une capture ciblée Extended Events contenant attention et les événements de fin ou d'erreur pertinents. Attention prouve que le client a demandé l'arrêt, mais ne distingue pas une action utilisateur, une échéance ou un problème du client.

L'annulation ne garantit pas la fermeture de toutes les transactions explicites. L'application doit gérer le cycle de vie de celles qu'elle possède. Après un échec, tentez leur rollback, traitez les erreurs de nettoyage et abandonnez une connexion dont l'état utilisable reste inconnu. Un bloc CATCH SQL ne couvre pas à lui seul tous les cas d'attention client.

Inversement, un composant ne doit pas annuler arbitrairement une transaction appartenant à son appelant. Le contrat doit préciser qui ouvre, valide et abandonne le travail. Cette responsabilité compte autant que la valeur du délai.

Donner une identité stable aux reprises

Imaginez une opération comparable à un paiement, validée avant la perte de réponse. Une reprise avec une nouvelle identité peut l'insérer deux fois. Attribuez une clé d'idempotence stable au commandement métier et imposez son unicité en base. Conservez le résultat nécessaire pour répondre à une nouvelle soumission de cette même clé.

L'enregistrement de déduplication et la modification métier doivent être validés ensemble. Deux transactions distinctes peuvent laisser une clé enregistrée sans opération effectuée. Si la même clé revient avec un contenu différent, rejetez cette incohérence.

Limitez les tentatives et espacez-les uniquement pour les erreurs déclarées récupérables par le contrat. Multiplier les requêtes ne résout pas une chaîne de blocage. Un état de commit inconnu demande une recherche du résultat existant. Testez l'annulation pendant l'exécution, pendant un blocage et la perte de réponse après validation.

Un délai supérieur peut convenir à un export volontairement long, mais mesurez les ressources immobilisées et l'impact sur les utilisateurs interactifs. L'objectif est une échéance claire et un résultat transactionnel connu, pas simplement une erreur repoussée.

Références techniques: Microsoft Learn: Query timeout troubleshooting · Microsoft Learn: SET LOCK_TIMEOUT · Microsoft Learn: XACT_STATE.

Question sur cet article

Vous avez une question sur ce sujet ?

Expliquez ce que vous évaluez ou le point qui vous bloque. Nous vous répondrons avec une recommandation pratique.

Inquiries are not enabled in this preview.

Poser une question sur cet article