Ketika catatan terkunci di Oracle, bisakah kita tahu catatan mana yang dikunci?

10

Ketika rekaman dikunci, bisakah kita tahu yang mana yang dikunci?

Bagaimana saya bisa mendapatkan record rowid atau info lainnya?


Saya bisa mendapatkan info dengan sql ini

SELECT c.ROW_WAIT_OBJ#,c.ROW_WAIT_FILE#,c.ROW_WAIT_BLOCK#,c.ROW_WAIT_ROW#
   FROM v$locked_object a, dba_objects b, v$session c    
WHERE a.object_id = b.object_id    
    AND a.SESSION_ID = c.sid(+) 

Saya menemukan metode di web untuk mendapatkan rowid dengan menggunakan fungsi DBMS_ROWID.ROWID_CREATE()

Tapi sepertinya itu tidak berhasil.

iafanda
sumber
2
Anda hanya dapat melihat kunci yang menunggu beberapa proses, bukan yang dipegang oleh suatu transaksi.
a_horse_with_no_name
@a_horse_with_no_name - v $ lock menunjukkan kunci yang dipegang oleh transaksi
Chris Saxon
@ChrisSaxon: Anda benar. Saya merujuk pada fakta bahwa Anda tidak dapat melihat baris mana yang telah dikunci - saya seharusnya lebih jelas.
a_horse_with_no_name
Oracle (sebaliknya dari database lain) tidak memiliki struktur bersama untuk kunci. Ini membuat basis data scalable, tetapi di sisi lain Anda tidak dapat melihat semua kunci. Kunci disimpan dalam blok basis data secara langsung. Pada saat seseorang diblokir struktur "pemegang-pelayan" dibuat. Kemudian Anda akan melihat pasangan ini di V$LOCK.
ibre5041

Jawaban:

13

Anda tidak dapat benar-benar daftar semua baris yang dikunci oleh sesi. Namun, begitu suatu sesi diblokir oleh orang lain, Anda dapat menemukan sesi / baris mana yang memblokirnya.

Oracle tidak memelihara daftar kunci baris individual. Sebaliknya, kunci terdaftar langsung di dalam baris itu sendiri - anggap saja sebagai kolom tambahan.

Anda dapat menemukan sesi mana yang telah mendapatkan kunci pada objek melalui V$LOCKtampilan, tetapi ini hanya akan mencantumkan informasi umum, bukan pada tingkat baris.

Dengan tampilan ini Anda juga dapat menemukan apakah suatu sesi diblokir oleh orang lain. Dalam hal itu, jika suatu sesi diblokir oleh sesi lain, informasi baris ditampilkan dalam V$SESSIONinformasi.

Anda dapat mengambil rowid, mari kita buat contoh dengan 2 sesi:

SESSION1> create table test as select * from all_objects;

Table created

SESSION1> select rowid from test where object_name = 'TEST' for update;

ROWID
------------------
AAMnFEAAaAAALTDAAz

/* setting identifiers to help with identifying this session later */
SESSION2> exec dbms_application_info.set_client_info('012345');

PL/SQL procedure successfully completed

SESSION2> select 1 from test where object_name = 'TEST' for update;
/*  this will block */

Sesi 2 sekarang menunggu pada Sesi 1. Kita dapat menemukan deretan pemblokiran dengan:

SESSION1> SELECT o.object_name,
       2         dbms_rowid.ROWID_CREATE (1,
       3                                  s.ROW_WAIT_OBJ#,
       4                                  s.ROW_WAIT_FILE#,
       5                                  s.ROW_WAIT_BLOCK#,
       6                                  s.ROW_WAIT_ROW#) rid
       7     FROM dba_objects o, v$session s
       8    WHERE o.object_id = s.row_wait_obj#
       9      AND s.client_info = '012345';

OBJECT_NAME     RID
--------------- ------------------
TEST            AAMnFEAAaAAALTDAAz

Untuk bacaan lebih lanjut: deskripsi proses oleh Tom Kyte .

Vincent Malgrat
sumber
3

Anda dapat menemukan semua kunci tabel di database Oracle dengan menjalankan kueri berikut

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a ,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
Baji Shaik
sumber