J'essaie de comprendre / apprendre à retrouver les détails d'une session bloquée.
J'ai donc créé la configuration suivante:
create table foo (id integer not null primary key, some_data varchar(20));
insert into foo values (1, 'foo');
commit;
Maintenant, je me connecte deux fois à la base de données à partir de deux clients différents.
La première session émet:
begin transaction
update foo set some_data = 'update'
where id = 1;
Je ne m'engage pas explicitement là-bas afin de garder les verrous.
Dans la deuxième session, j'émets la même déclaration et bien sûr que l'on attend en raison du verrouillage. Maintenant, j'essaie d'utiliser les différentes requêtes flottantes pour voir que la session 2 attend la foo
table.
sp_who2
affiche ce qui suit (j'ai supprimé certaines colonnes pour n'afficher que les informations importantes):
SPID | Statut | BlkBy | DBName | Commande | SPID | DEMANDÉ ----- + -------------- + ------- + ---------- + ---------- -------- + ------ + ---------- 52 | dormir | . | foodb | EN ATTENTE DE COMMANDE | 52 | 0 53 | dormir | . | foodb | EN ATTENTE DE COMMANDE | 53 | 0 54 | SUSPENDU | 52 | foodb | MISE À JOUR | 54 | 0 56 | RUNNABLE | . | foodb | SÉLECTIONNEZ DANS | 56 | 0
Cela est attendu, la session 54 est bloquée par les modifications non validées de la session 52.
L'interrogation le sys.dm_os_waiting_tasks
montre également. La déclaration:
select session_id, wait_type, resource_address, resource_description
from sys.dm_os_waiting_tasks
where blocking_session_id is not null;
Retour:
session_id | wait_type | adresse_ressource | description_ressource ----------- + ----------- + -------------------- + ----- -------------------------------------------------- -------------------------- 54 | LCK_M_X | 0x000000002a35cd40 | hobtid de verrouillage = 72057594046054400 dbid = 6 id = mode lock4ed1dd780 = X associatedObjectId = 72057594046054400
Encore une fois, cela est attendu.
Mon problème est que je ne peux pas trouver comment trouver le nom d'objet réel que la session 54 attend.
J'ai trouvé plusieurs requêtes qui se joignent sys.dm_tran_locks
et sys.dm_os_waiting_tasks
comme ceci:
SELECT ....
FROM sys.dm_tran_locks AS l
JOIN sys.dm_os_waiting_tasks AS wt ON wt.resource_address = l.lock_owner_address
Mais dans mon scénario de test ci-dessus, cette jointure ne renvoie rien. Donc, cette jointure est incorrecte ou dm_tran_locks
ne contient pas réellement les informations que je recherche.
Donc, ce que je recherche, c'est une requête qui renvoie quelque chose comme:
"la session 54 attend un verrou dans la tablefoo
".
Quelques informations de fond:
Le vrai problème que j'essaie de résoudre est un peu plus compliqué, mais se résume à la question "sur quelle table la session 54 attend-elle". Le problème en question implique une procédure stockée de grande taille qui met à jour plusieurs tables et une sélection dans une vue qui accède à certaines de ces tables. L' select
instruction est bloquée même si l'isolement de l'instantané et la lecture de l'instantané validé sont activés. Déterminer pourquoi la sélection est bloquée (ce que je pensais ne serait pas possible si l'isolement de l'instantané est activé) sera la prochaine étape.
Dans un premier temps, j'aimerais savoir ce que cette session attend.