Sto cercando di capire / imparare a rintracciare i dettagli di una sessione bloccata.
Quindi ho creato la seguente configurazione:
create table foo (id integer not null primary key, some_data varchar(20));
insert into foo values (1, 'foo');
commit;
Ora mi collego al database due volte da due client diversi.
I primi numeri della sessione:
begin transaction
update foo set some_data = 'update'
where id = 1;
Non mi impegno esplicitamente lì per mantenere i blocchi.
Nella seconda sessione rilascio la stessa dichiarazione e, naturalmente, si attende a causa del blocco. Ora sto cercando di utilizzare le diverse query fluttuanti per vedere che la sessione 2 è in attesa del foo
tavolo.
sp_who2
mostra quanto segue (ho rimosso alcune colonne per mostrare solo le informazioni importanti):
SPID | Stato | BlkBy | DBName | Comando | SPID | IDRichiesta ----- + -------------- + ------- + ---------- + ---------- -------- + ------ + ---------- 52 | dormire | . | foodb | COMANDO IN ATTESA | 52 | 0 53 | dormire | . | foodb | COMANDO IN ATTESA | 53 | 0 54 | SOSPESO | 52 | foodb | AGGIORNAMENTO | 54 | 0 56 | FUNZIONABILE | . | foodb | SELEZIONA IN | 56 | 0
Ciò è previsto, la sessione 54 è bloccata dalle modifiche non impegnate dalla sessione 52.
Anche le query sys.dm_os_waiting_tasks
mostrano questo. La dichiarazione:
select session_id, wait_type, resource_address, resource_description
from sys.dm_os_waiting_tasks
where blocking_session_id is not null;
ritorna:
session_id | wait_type | indirizzo_risorse | resource_description ----------- + ----------- + -------------------- + ----- -------------------------------------------------- -------------------------- 54 | LCK_M_X | 0x000000002a35cd40 | keylock hobtid = 72057594046054400 dbid = 6 id = lock4ed1dd780 mode = X associateObjectId = 72057594046054400
Anche questo è previsto.
Il mio problema è che non riesco a capire come trovare il nome effettivo dell'oggetto che la sessione 54 sta aspettando.
Ho trovato diverse query che si stanno unendo sys.dm_tran_locks
e in sys.dm_os_waiting_tasks
questo modo:
SELECT ....
FROM sys.dm_tran_locks AS l
JOIN sys.dm_os_waiting_tasks AS wt ON wt.resource_address = l.lock_owner_address
Ma nel mio scenario di test sopra questo join non restituisce nulla. Quindi o quel join è sbagliato o in dm_tran_locks
realtà non contiene le informazioni che sto cercando.
Quindi quello che sto cercando è una query che restituisca qualcosa del tipo:
"la sessione 54 è in attesa di un blocco nella tabellafoo
".
Alcune informazioni di base:
Il problema della vita reale che sto cercando di risolvere è un po 'più complicato, ma si riduce alla domanda "su quale tavolo è in attesa la sessione 54". Il problema in questione riguarda una procedura memorizzata di grandi dimensioni che aggiorna diverse tabelle e una selezione da una vista che accede ad alcune di quelle tabelle. L' select
istruzione è bloccata anche se abbiamo l'isolamento dello snapshot e la lettura dello snapshot di commit è abilitata. Capire perché la selezione è bloccata (cosa che pensavo non sarebbe possibile se fosse abilitato l'isolamento dello snapshot) sarà il prossimo passo.
Come primo passo vorrei scoprire cosa sta aspettando quella sessione.