เมื่อบันทึกถูกล็อคใน Oracle เราจะทราบได้อย่างไรว่าบันทึกใดถูกล็อค


10

เมื่อบันทึกถูกล็อคเราจะทราบได้อย่างไรว่ารายการใดถูกล็อก

ฉันจะรับเรคคอร์ด rowid หรือข้อมูลอื่นได้อย่างไร


ฉันสามารถรับข้อมูลบางอย่างจาก sql นี้

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(+) 

ฉันพบวิธีในเว็บเพื่อรับ rowid โดยใช้ฟังก์ชั่น DBMS_ROWID.ROWID_CREATE()

แต่ดูเหมือนจะไม่ทำงาน


2
คุณสามารถเห็นได้เฉพาะการล็อกที่กระบวนการบางอย่างกำลังรอไม่ใช่การล็อคที่ทำโดยธุรกรรม
a_horse_with_no_name

@a_horse_with_no_name - v $ lock แสดงให้คุณเห็นถึงการล็อคการทำธุรกรรม
Chris Saxon

@ChrisSaxon: คุณพูดถูก ฉันหมายถึงความจริงที่ว่าคุณไม่สามารถเห็นแถวที่ถูกล็อค - ฉันควรจะชัดเจนมากขึ้น
a_horse_with_no_name

Oracle (ตรงกันข้ามกับฐานข้อมูลอื่น) ไม่มีโครงสร้างที่ใช้ร่วมกันสำหรับล็อค สิ่งนี้ทำให้ฐานข้อมูลสามารถปรับขนาดได้ แต่ในทางกลับกันคุณจะไม่เห็นล็อคทั้งหมด ล็อคจะถูกเก็บไว้ในบล็อกฐานข้อมูลโดยตรง ในช่วงเวลาที่ใครบางคนถูกบล็อกโครงสร้าง "เจ้ามือพนักงานเสิร์ฟ" ถูกสร้างขึ้น จากนั้นคุณจะเห็นคู่นี้V$LOCKมา
ibre5041

คำตอบ:


13

คุณไม่สามารถแสดงรายการทุกแถวที่ถูกล็อคโดยเซสชัน อย่างไรก็ตามเมื่อเซสชันถูกบล็อกโดยอีกคุณสามารถค้นหาเซสชัน / แถวที่ถูกบล็อก

Oracle ไม่เก็บรายการล็อคแถวแต่ละรายการ ค่อนข้างล็อคถูกลงทะเบียนโดยตรงภายในแถว - คิดว่ามันเป็นคอลัมน์พิเศษ

คุณสามารถค้นหาเซสชันที่ได้รับการล็อกบนวัตถุผ่านV$LOCKมุมมอง แต่จะแสดงเฉพาะข้อมูลทั่วไปไม่ใช่ระดับแถว

ด้วยมุมมองนี้คุณสามารถค้นหาได้ว่าเซสชันถูกบล็อกโดยอีกเซสชันหนึ่งหรือไม่ ในกรณีนั้นหากเซสชันถูกบล็อกโดยเซสชันอื่นข้อมูลแถวจะปรากฏในV$SESSIONข้อมูล

คุณสามารถดึง rowid มาสร้างตัวอย่างด้วย 2 เซสชัน:

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 */

ช่วงที่ 2 กำลังรอเซสชัน 1 เราสามารถค้นพบแถวการบล็อกด้วย:

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

สำหรับการอ่านเพิ่มเติมที่: รายละเอียดของกระบวนการโดยทอม Kyte


3

คุณสามารถค้นหาล็อคตารางทั้งหมดในฐานข้อมูล Oracle โดยเรียกใช้แบบสอบถามต่อไปนี้

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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.