Ich versuche zu verstehen / zu lernen, wie man die Details einer blockierten Sitzung aufspürt.
Also habe ich folgendes Setup erstellt:
create table foo (id integer not null primary key, some_data varchar(20));
insert into foo values (1, 'foo');
commit;
Jetzt verbinde ich mich zweimal von zwei verschiedenen Clients aus mit der Datenbank.
Die ersten Fragen der Sitzung:
begin transaction
update foo set some_data = 'update'
where id = 1;
Ich verpflichte mich dort ausdrücklich nicht , die Schlösser zu behalten.
In der zweiten Sitzung gebe ich die gleiche Aussage ab und natürlich, dass man wegen Sperrens wartet. Jetzt versuche ich, die verschiedenen Abfragen zu verwenden, um zu sehen, dass Sitzung 2 auf den foo
Tisch wartet .
sp_who2
Folgendes wird angezeigt (ich habe einige Spalten entfernt, um nur die wichtigen Informationen anzuzeigen):
SPID | Status | BlkBy | DBName | Befehl | SPID | ANFRAGE ID ----- + -------------- + ------- + ---------- + ---------- -------- + ------ + ---------- 52 | schlafen | . | foodb | BEFEHL ERWARTEN | 52 | 0 53 | schlafen | . | foodb | BEFEHL ERWARTEN | 53 | 0 54 | AUSGEHÄNGT | 52 | foodb | UPDATE | 54 | 0 56 | RUNNABLE | . | foodb | SELECT INTO | 56 | 0
Dies wird erwartet, Sitzung 54 wird durch die nicht festgeschriebenen Änderungen von Sitzung 52 blockiert.
Das sys.dm_os_waiting_tasks
zeigt auch die Abfrage . Die Aussage:
select session_id, wait_type, resource_address, resource_description
from sys.dm_os_waiting_tasks
where blocking_session_id is not null;
kehrt zurück:
session_id | wait_type | resource_address | resource_description ----------- + ----------- + -------------------- + ----- -------------------------------------------------- -------------------------- 54 | LCK_M_X | 0x000000002a35cd40 | Tastensperre hobtid = 72057594046054400 dbid = 6 id = lock4ed1dd780 mode = X associatedObjectId = 72057594046054400
Auch dies wird erwartet.
Mein Problem ist, dass ich nicht herausfinden kann, wie ich den tatsächlichen Objektnamen finde, auf den Sitzung 54 wartet.
Ich habe mehrere Suchanfragen gefunden, die sich anschließen sys.dm_tran_locks
und sys.dm_os_waiting_tasks
wie folgt lauten :
SELECT ....
FROM sys.dm_tran_locks AS l
JOIN sys.dm_os_waiting_tasks AS wt ON wt.resource_address = l.lock_owner_address
In meinem obigen Testszenario gibt dieser Join jedoch nichts zurück. Entweder ist dieser Join falsch oder dm_tran_locks
enthält nicht die Informationen, nach denen ich suche.
Also, was ich suche, ist eine Abfrage, die so etwas wie zurückgibt:
" Sitzung 54 wartet auf eine Sperre in der Tabellefoo
".
Einige Hintergrundinformationen:
Das Problem im wirklichen Leben, das ich zu lösen versuche, ist etwas komplizierter, läuft aber auf die Frage hinaus, auf welchen Tisch Sitzung 54 wartet. Bei dem fraglichen Problem handelt es sich um eine umfangreiche gespeicherte Prozedur, die mehrere Tabellen aktualisiert und eine Auswahl aus einer Ansicht, die auf einige dieser Tabellen zugreift. Die select
Anweisung wird blockiert, obwohl die Snapshot-Isolierung und der Lese-Commit-Snapshot aktiviert sind. Der nächste Schritt besteht darin, herauszufinden, warum die Auswahl blockiert ist (was meiner Meinung nach nicht möglich wäre, wenn die Snapshot-Isolierung aktiviert ist).
Als ersten Schritt möchte ich herausfinden, worauf diese Sitzung wartet.