É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: