当Oracle中的一条记录被锁定时,我们能知道哪条记录被锁定了吗?

iaf*_*nda 12 oracle locking

当一条记录被锁定时,我们能知道哪个记录被锁定了吗?

如何获取记录 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(+) 
Run Code Online (Sandbox Code Playgroud)

我在 web 中找到了一种使用函数获取 rowid 的方法 DBMS_ROWID.ROWID_CREATE()

但它似乎不起作用。

Vin*_*rat 14

您无法真正列出会话锁定的所有行。但是,一旦一个会话被另一个会话阻止,您就可以找到哪个会话/行阻止了它。

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 */
Run Code Online (Sandbox Code Playgroud)

会话 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
Run Code Online (Sandbox Code Playgroud)

进一步阅读:Tom Kyte 对该过程描述