web-dev-qa-db-fra.com

SPID endormi bloquant d'autres transactions

J'ai vraiment du mal à localiser certains blocages que nous rencontrons.

Le statut du SPID bloquant la racine est 'sleep', le cmd est 'AWAITING COMMAND', et le sqltext est SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

Lorsque j'affiche le rapport Top Transactions by Blocked Transactions Count, l'instruction SQL de blocage est "-".

J'ai effectué une trace sur le SQL et lorsque le blocage se produit en traçant le SPID de blocage racine, mais cela ne m'a vraiment conduit nulle part. La dernière instruction de trace est identique à la sqltext ci-dessus SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

J'ai vérifié toutes les procédures stockées connexes que je peux trouver pour m'assurer qu'elles ont des instructions TRY/CATCH BEGIN TRAN/COMMIT TRAN/ROLLBACK TRAN (nous utilisons des procédures stockées pour tout, donc aucune instruction autonome n'est exécutée). Ce problème vient de se produire au cours des dernières 24 heures et personne ne prétend avoir apporté de modifications au système.

Solution: une de nos procédures stockées rarement utilisées avait une erreur avec un insert (le nombre de colonnes ne correspondait pas), mais nous sommes encore confus sur ce qui se passait exactement.

Lorsque vous examinez toutes les informations de trace, l'instruction EXEC pour cette procédure stockée a parfois été répertoriée, mais JAMAIS juste avant que le BLOC ne se produise sur le SPID bloquant. Il semblait que lors du démarrage du blocage, la trace n'enregistrait pas l'exécution (ni aucune des instructions qu'elle contenait). Cependant, il y a d'autres moments où la trace a enregistré son exécution et aucun blocage ne s'est produit.

Le rapport d'erreur de procédure stockée est venu d'un utilisateur, et j'ai pu trouver plusieurs instructions EXEC dans les traces et les exécuter dans SSMS. À aucun moment lorsque je les ai exécutés, nous avons eu un blocage ou ils se sont bloqués. Ils ont fonctionné comme prévu (le bloc catch s'est déclenché et a annulé la transaction après l'erreur). Après avoir résolu la correction de la procédure stockée, nous n'avons pas revu le problème.

16
Brad

D'après les commentaires, je suppose que vous avez eu un délai d'expiration de commande côté client qui a abandonné la requête SQL. Cela n'annule pas la transaction car la connexion reste ouverte sur SQL Server en raison du regroupement de connexions.

Donc, vous devez utiliser SET XACT_ABORT ON ou ajouter du code de restauration client

Voir SQL Server Transaction Timeout pour tous les détails sanglants

10
gbn

Utilisez le most_recent_sql_handle dans sys.dm_exec_connections pour voir la dernière instruction exécutée.

SELECT  t.text,
        QUOTENAME(OBJECT_SCHEMA_NAME(t.objectid, t.dbid)) + '.'
        + QUOTENAME(OBJECT_NAME(t.objectid, t.dbid)) proc_name,
        c.connect_time,
        s.last_request_start_time,
        s.last_request_end_time,
        s.status
FROM    sys.dm_exec_connections c
JOIN    sys.dm_exec_sessions s
        ON c.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE   c.session_id = 72;--your blocking spid

Vérifiez également s'il y a des transactions ouvertes pour ce spid

SELECT  st.transaction_id,
        at.name,
        at.transaction_begin_time,
        at.transaction_state,
        at.transaction_status
FROM    sys.dm_tran_session_transactions st
JOIN    sys.dm_tran_active_transactions at
        ON st.transaction_id = at.transaction_id
WHERE   st.session_id = 72;--your blocking spid
9
Sebastian Meine

Avez-vous essayé d'utiliser sp_whoisactive d'Adam Machanic? Il y a une option pour obtenir la commande externe pour voir si elle est vraiment dans un proc. Il se peut que l'application maintienne ouverte une transaction au lieu de la valider. Essayez également de regarder DBCC OPENTRAN .