当记录在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 2013年

@a_horse_with_no_name-v $ lock向您显示交易持有的锁
Chris Saxon

@ChrisSaxon:你是对的。我指的是您看不到哪些已被锁定的事实-我应该更加清楚。
a_horse_with_no_name

Oracle(与其他数据库相反)没有任何锁共享结构。这使数据库具有可伸缩性,但另一方面,您看不到所有锁。锁直接存储在数据库块中。在有人被阻塞的那一刻,创建了一个“持有者-等待者”结构。然后您会在中看到这对V$LOCK
ibre5041 2015年

Answers:


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

进一步阅读:Tom 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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.