Étendre la réponse de Mark ...
Lorsqu'un événement de délai d'expiration du client se produit (.net CommandTimeout par exemple), le client envoie un "ABORT" à SQL Server. SQL Server abandonne alors simplement le traitement des requêtes. Aucune transaction n'est annulée, aucun verrou n'est libéré.
Maintenant, la connexion est renvoyée au pool de connexions, elle n'est donc pas fermée sur SQL Server. Si cela se produit (via KILL ou redémarrage du client, etc.), les transactions + les verrous seront effacés. Notez que sp_reset_connection ne les effacera pas ou ne les effacera pas, même s'il est annoncé pour le faire
Ces détritus de l'avortement bloqueront d'autres processus.
La façon de rendre les transactions + verrous SQL Server claires sur le délai d'expiration du client (strictement, les événements ABORT) consiste à utiliser SET XACT_ABORT ON.
Vous pouvez vérifier cela en ouvrant 2 fenêtres de requête dans SSMS:
Fenêtre 1:
Dans le menu Query..Query Options, définissez un délai d'expiration de 5 secondes, puis exécutez cette
BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout
Fenêtre 2, cela attendra pour toujours (ou atteindra votre délai d'attente)
SELECT * FROM sometable
SET XACT_ABORT ON a aussi des effets secondaires intéressants:
- @@ TRANCOUNT est défini sur zéro lors de la restauration implicite mais l'erreur 266 est supprimée (cela se produit si @@ TRANCOUNT est différent à l'entrée et à la sortie d'un proc stocké)
- XACT_STATE sera -1 (c'est "condamné")
La combinaison de cela signifie que vous ne pouvez pas utiliser SAVEPOINTS (bien que je ne me souvienne pas du comportement exact) pour les validations / annulations partielles. Qui me convient
Liens SO sur SET XACT_ABORT:
Sur les proc stockés imbriqués:
Sur sp_reset_connection:
Je réponds à cette question avec hésitation car il n'y a pas suffisamment d'informations dans votre description du problème pour être sûr à 100% que c'est le meilleur conseil. "Suspend ou lève une exception" suggère que la source du problème n'est pas bien comprise, alors soyez prudent.
La solution la plus simple à cela est probablement
SET XACT_ABORT ON
.XACT_ABORT
détermine si SQL Server annulera une transaction en cas d'erreur d'exécution. La valeur par défautSET XACT_ABORT OFF
annulera uniquement l'instruction qui a provoqué une erreur, laissant toute transaction parent ouverte.L'effet secondaire "gotcha" du paramètre par défaut est qu'un délai d'attente peut provoquer exactement le même problème, une transaction ouverte qui est la responsabilité des clients à gérer et à annuler. Si le client n'essaie pas / catch / rollback, la transaction restera ouverte jusqu'à ce qu'elle soit traitée avec (et je cite @gbn) l'ultra-violence de
KILL <spid>
.Les articles d' Erland Sommarskog souvent cités sur la gestion des erreurs dans SQL Server contiennent tous les antécédents et la stratégie dont vous avez besoin pour gérer ces scénarios et plus encore.
Modifier (commentaire suivant): Pour identifier les transactions ouvertes, sp_whoisactive est probablement la fonctionnalité la plus complète.
la source