使用Oracle,是否可以在执行select语句时指示哪些行当前被锁定(哪些不是)(我不想锁定任何行,只能显示哪些行被锁定)?
例如,一个伪列将对该行返回锁定/事务:
SELECT lockname FROM emp;
答案 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%的时间内都不准确。
会话不等待一行,他们等待修改该行的事务结束。大多数情况下,这两个概念是相同的,但不是在您开始使用保存点时。
例如:
很抱歉,如果这令人困惑。您可能希望单步执行OMG Ponies提供的链接,然后使用保存点再次尝试。