显示在Oracle中锁定的行

时间:2011-03-02 20:17:45

标签: oracle locking

使用Oracle,是否可以在执行select语句时指示哪些行当前被锁定(哪些不是)(我不想锁定任何行,只能显示哪些行被锁定)?

例如,一个伪列将对该行返回锁定/事务:
    SELECT lockname FROM emp;

3 个答案:

答案 0 :(得分:5)

你可以做的一件事就是 - 虽然它不是非常有效,所以我不想将它用于大型数据集。创建行级函数以尝试锁定行。如果失败,则该行已被锁定

    CREATE OR REPLACE FUNCTION is_row_locked (v_rowid ROWID, table_name VARCHAR2)
   RETURN varchar2
IS
   x   NUMBER;
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   EXECUTE IMMEDIATE    'Begin
                           Select 1 into :x from '
                              || table_name
                              || ' where rowid =:v_rowid for update nowait;
                         Exception
                            When Others Then
                              :x:=null;
                         End;'
   USING OUT x, v_rowid;

   -- now release the lock if we got it. 
   ROLLBACK;

   IF x = 1
   THEN
      RETURN 'N';
   ELSIF x IS NULL
   THEN
      RETURN 'Y';
   END IF;
END;
/

然后你可以

Select field1, field2, is_row_locked(rowid, 'MYTABLE') from mytable;

它会起作用,但它不漂亮也不高效。

实际上,它只有一种兑换质量 - 即使您在链接文档中所需的各种v $表上没有选择权限,它也会起作用。但是,如果你有私人,肯定会走另一条路。

答案 1 :(得分:2)

  

执行select语句时可以指示当前哪些行被锁定(哪些不是)

SELECT语句永远不会锁定任何行 - 除非您通过使用FOR UPDATE来询问它。

如果要查看由于SELECT ... FOR UPDATE(或实际更新)而保留的锁,可以查询v $ lock系统视图。

请参阅OMG Pony发布的链接,以获取有关如何使用该视图的示例。

答案 2 :(得分:2)

我认为@Michael Broughton的答案是永远有效的唯一方法。这是因为V $ LOCK在100%的时间内都不准确。

会话不等待一行,他们等待修改该行的事务结束。大多数情况下,这两个概念是相同的,但不是在您开始使用保存点时。

例如:

  • 会话1创建一个保存点并修改一行。
  • 会话2尝试修改相同的内容 行,但看到会话1已经有该行, 并等待第1阶段结束。
  • 会话1回滚到 保存点。这将删除其条目 来自国际交易日志,但并没有结束 交易。第二场会议仍然是 等待会议1.根据 V $ LOCK会话2仍在等待 那一排,但那不是真的 因为现在会话3可以修改它 行。 (如果会话1执行了 提交或回滚,会话2将 等待会议3。)

很抱歉,如果这令人困惑。您可能希望单步执行OMG Ponies提供的链接,然后使用保存点再次尝试。