显示在Oracle中锁定的行

显示在Oracle中锁定的行,oracle,locking,Oracle,Locking,使用Oracle,在执行select语句时,是否可以指示哪些行当前已锁定(哪些未锁定)(我不想锁定任何行,只想显示哪些已锁定) 例如,将针对行返回锁/事务的伪列: 从emp中选择lockname 您可以做的一件事是——尽管它的效率不是很高,所以我不想将其用于大型数据集。创建行级函数以尝试锁定行。如果失败,则该行已被锁定 CREATE OR REPLACE FUNCTION is_row_locked (v_rowid ROWID, table_name VARCHAR2) RETU

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

例如,将针对行返回锁/事务的伪列:

从emp中选择lockname

您可以做的一件事是——尽管它的效率不是很高,所以我不想将其用于大型数据集。创建行级函数以尝试锁定行。如果失败,则该行已被锁定

    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$表上没有select PRIV,它也会起作用。不过,如果你有隐私权,一定要走另一条路

在执行select语句时,是否可以指示哪些行当前已锁定(哪些未锁定)

SELECT语句永远不会锁定任何行,除非您使用FOR UPDATE命令它锁定

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


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

我认为@Michael Broughton的答案是唯一有效的方法。这是因为V$LOCK在所有情况下都不是100%准确的

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

例如:

  • 会话1创建保存点并修改行
  • 会话2尝试修改相同的内容 行,但会话1已具有该行, 并等待会话1完成
  • 会话1回滚到 保存点。这将删除其条目 从国际交易日志中删除,但不结束 交易第二节仍在继续 正在等待第1课时。根据 V$LOCK会话2仍在等待 那场争吵,但那不是真的 因为现在会话3可以修改它 一行(如果会话1执行 提交或回滚,会话2将 等待第3课时。)

对不起,如果这让人困惑的话。您可能希望单步通过OMG Ponies提供的链接,然后使用保存点重试。

为什么要显示哪些行被锁定?如果目的是防止某人尝试锁定其他人正在处理的行,则使用SKIP LOCKED(跳过锁定)选择未锁定的行可能更容易(取决于Oracle版本,这可能是可用的,也可能是不可用的/有文档记录的)@OMG Ponies:没有阻塞,所以将值放入dbms_rowid.rowid_create from v$session会创建一个表中不存在的rowid(至少这就是为什么我猜它不起作用的原因)@贾斯汀:是的,这是我的意图。SKIP LOCKED听起来可能有用。我不能走另一条路线,因为没有阻塞,所以我无法从v$会话信息生成rowid。请求锁是确定是否有锁的唯一方法吗?我在线阅读的所有文本都表明行锁是应用于该行的事务id。让人觉得这应该是很容易得到的东西:(@Cwoo是什么让你觉得获得每行的锁定状态那么容易?这只是其中一个你不能忘记并发系统和孤立事务的复杂性的地方。Cwoo,请记住,通常情况下,用户应该将事务控制权留给数据库,最好是在出现情况时做出反应。a第二,对于大容量系统,数据库可能会在内存中执行大量事务控制,而不是通过写入表结构来增加开销。即使我的查询确实有效,对于一个大的表,在您执行获取并尝试处理结果时,谁能说锁仍然是您执行反编译时的锁呢给他们下定义?毕竟,大多数人并不存在很长时间,对吧,我想这可能是我不应该尝试去做的事情!