Khi một bản ghi bị khóa trong Oracle, chúng ta có thể biết bản ghi nào bị khóa không?


10

Khi một bản ghi bị khóa, chúng ta có thể biết bản nào bị khóa không?

Làm thế nào tôi có thể nhận được bản ghi hàng hay thông tin khác?


Tôi có thể nhận được một số thông tin của sql này

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

Tôi tìm thấy một phương thức trong web để có được rowid bằng cách sử dụng hàm DBMS_ROWID.ROWID_CREATE()

Nhưng nó dường như không hoạt động.


2
Bạn chỉ có thể thấy các khóa mà một số quy trình đang chờ, chứ không phải các khóa được giữ bởi một giao dịch.
a_horse_with_no_name

@a_horse_with_no_name - v $ lock hiển thị cho bạn các khóa được giữ bởi một giao dịch
Chris Saxon

@ChrisSaxon: Bạn nói đúng. Tôi đã đề cập đến thực tế là bạn không thể nhìn thấy mà hàng đã bị khóa - Tôi cần phải có được rõ ràng hơn.
a_horse_with_no_name

Oracle (trái với các cơ sở dữ liệu khác) không có bất kỳ cấu trúc chia sẻ nào cho các khóa. Điều này làm cho cơ sở dữ liệu có thể mở rộng, nhưng mặt khác, bạn không thể thấy tất cả các khóa. Khóa được lưu trữ trong khối cơ sở dữ liệu trực tiếp. Trong thời điểm khi ai đó bị chặn, một cấu trúc "người giữ bàn" được tạo ra. Sau đó, bạn sẽ thấy cặp này trong V$LOCK.
ioust5041

Câu trả lời:


13

Bạn có thể không thực sự liệt kê tất cả các hàng đang được khóa bởi một phiên làm việc. Tuy nhiên, một khi phiên bị chặn bởi một phiên khác, bạn có thể tìm thấy phiên / hàng nào đang chặn phiên đó.

Oracle không duy trì một danh sách các khóa hàng riêng lẻ. Thay vào đó, các khóa được đăng ký trực tiếp bên trong các hàng - hãy nghĩ về nó như một cột phụ.

Bạn có thể tìm thấy phiên nào đã có được khóa trên một đối tượng thông qua V$LOCKchế độ xem, nhưng điều này sẽ chỉ liệt kê thông tin chung, không phải ở cấp hàng.

Với chế độ xem này, bạn cũng có thể tìm thấy nếu một phiên bị chặn bởi một phiên khác. Trong trường hợp đó, nếu một phiên bị chặn bởi một phiên khác, thông tin hàng được hiển thị trong V$SESSIONthông tin.

Bạn có thể truy xuất rowid, hãy xây dựng một ví dụ với 2 phiên:

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

Phần 2 hiện đang chờ trong Phần 1. Chúng ta có thể khám phá hàng chặn với:

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

Để đọc thêm: một mô tả về quá trình của Tom Kyte .


3

Bạn có thể tìm thấy tất cả các khóa bảng trong cơ sở dữ liệu Oracle bằng cách chạy truy vấn sau

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.