Saya mencoba memahami / mempelajari cara melacak detail sesi yang diblokir.
Jadi saya membuat pengaturan berikut:
create table foo (id integer not null primary key, some_data varchar(20));
insert into foo values (1, 'foo');
commit;
Sekarang saya terhubung ke database dua kali dari dua klien yang berbeda.
Masalah sesi pertama:
begin transaction
update foo set some_data = 'update'
where id = 1;
Saya secara eksplisit tidak berkomitmen di sana untuk menjaga kunci.
Pada sesi kedua saya mengeluarkan pernyataan yang sama dan tentu saja orang menunggu karena penguncian. Sekarang saya mencoba menggunakan kueri yang berbeda untuk melihat bahwa sesi 2 sedang menunggu foo
tabel.
sp_who2
menunjukkan yang berikut (Saya menghapus beberapa kolom untuk hanya menampilkan informasi penting):
SPID | Status | BlkBy | DBName | Command | SPID | PERMINTAAN ----- + -------------- + ------- + ---------- + ---------- -------- + ------ + ---------- 52 | tidur | . | makanan | PERINTAH AWAITING | 52 | 0 53 | tidur | . | makanan | PERINTAH AWAITING | 53 | 0 54 | DITANGGUHKAN | 52 | makanan | PEMBARUAN | 54 | 0 56 | DIMINTA | . | makanan | PILIH KE DALAM | 56 | 0
Ini diharapkan, sesi 54 diblokir oleh perubahan yang tidak dilakukan dari sesi 52.
Pertanyaan sys.dm_os_waiting_tasks
juga menunjukkan ini. Pernyataan:
select session_id, wait_type, resource_address, resource_description
from sys.dm_os_waiting_tasks
where blocking_session_id is not null;
pengembalian:
session_id | wait_type | resource_address | resource_description ----------- + ----------- + -------------------- + ----- -------------------------------------------------- -------------------------- 54 | LCK_M_X | 0x000000002a35cd40 | kunci tombol hobtid = 72057594046054400 dbid = 6 id = mode lock4ed1dd780 = X relatedObjectId = 72057594046054400
Sekali lagi ini diharapkan.
Masalah saya adalah, saya tidak tahu bagaimana menemukan nama objek aktual yang ditunggu sesi 54.
Saya telah menemukan beberapa pertanyaan yang bergabung sys.dm_tran_locks
dan sys.dm_os_waiting_tasks
seperti ini:
SELECT ....
FROM sys.dm_tran_locks AS l
JOIN sys.dm_os_waiting_tasks AS wt ON wt.resource_address = l.lock_owner_address
Tetapi dalam skenario pengujian saya di atas bergabung ini tidak menghasilkan apa-apa. Jadi salah satu yang bergabung itu salah atau dm_tran_locks
tidak benar-benar mengandung informasi yang saya cari.
Jadi yang saya cari adalah kueri yang mengembalikan sesuatu seperti:
" sesi 54 sedang menunggu kunci dalam tabelfoo
".
Beberapa info latar belakang:
Masalah kehidupan nyata yang saya coba selesaikan sedikit lebih rumit, tetapi bermuara pada pertanyaan "pada tabel mana sesi 54 menunggu". Masalah yang dipermasalahkan melibatkan prosedur tersimpan berukuran besar yang memperbarui beberapa tabel dan memilih dari tampilan yang mengakses beberapa tabel tersebut. The select
pernyataan diblokir meskipun kita memiliki snapshot isolasi dan membaca berkomitmen snapshot diaktifkan. Mencari tahu mengapa pilih diblokir (yang saya pikir tidak akan mungkin jika isolasi snapshot diaktifkan) akan menjadi langkah berikutnya.
Sebagai langkah pertama saya ingin mencari tahu tentang apa yang menunggu sesi itu.
sumber
Jawaban:
Saya pikir ini melakukan apa yang Anda butuhkan.
sumber
Kamu bisa mencobanya :
sumber