选择未锁定的行oracle

时间:2013-01-01 20:03:57

标签: c# database oracle oracle11g

我在C#中有一个使用Oracle数据库的应用程序。 我需要一个查询来从oracle数据库中的表中获取未锁定的行。 如何选择所有未锁定的行?

是否有可以将此T-SQL(MS SQL Server)查询转换为Oracle方言的“翻译器”?

SELECT TOP 1 * FROM TableXY WITH(UPDLOCK, READPAST);

我对Oracle缺乏这样的功能感到有些失望。他们想让我使用AQ或什么?

3 个答案:

答案 0 :(得分:3)

Oracle确实具有此功能,特别是SELECT statement的SKIP LOCKED部分。引用:

  

SKIP LOCKED是处理竞争交易的另一种方式   这是锁定一些感兴趣的行。指定SKIP LOCKED指示   数据库尝试锁定WHERE子句指定的行   并跳过任何被发现已被另一个人锁定的行   事务。

文档继续说它是为多消费者队列设计的,但这并不意味着 在这种环境中使用它。虽然文档说这有一个很大的警告。您不能要求下一个N个未锁定的行 - 只有接下来的N行,其中将返回未锁定的行。

SELECT * 
  FROM TableXY 
 WHERE ROWNUM = 1
   FOR UPDATE SKIP LOCKED

请注意,如果您选择的表被锁定在独占模式,即您已经指示数据库不让任何其他会话锁定该表,则不会返回任何行直到独家锁定被释放。

答案 1 :(得分:1)

我最近遇到了同样的问题,在解决之后,我写了这篇博客文章:

http://nhisawesome.blogspot.com/2013/01/how-to-lock-first-unlocked-row-in-table.html

随时发表评论!感谢您的意见。

简短摘要:我选择了一堆记录,然后在尝试中使用SKIP LOCKED提示获取锁定,而不是选择第一个解锁的并锁定它。如果所选择的一个不可锁定,则转到下一个,直到获得锁定或没有锁定。

答案 2 :(得分:0)

选择更新nowait如果选择已锁定的行,则会出错。那是你要的吗?我很好奇你要解决的问题。除非您有长时间运行的事务,否则从一个时刻到下一个时刻的锁定将是暂时的。

示例:

创建表测试 (   COL1 NUMBER(10)NOT NULL,   COL2 VARCHAR2(20 BYTE)NOT NULL );

在测试中创建独特的索引TEST_PK (COL1);

ALTER TABLE TEST ADD(   CONSTRAINT TEST_PK   首要的关键   (COL1)   使用INDEX TEST_PK  );

SQL Session#1: SQL>插入测试值(1,'1111'); 已创建1行。 SQL>插入测试值(2,'2222'); 已创建1行。 SQL>承诺; 提交完成。 SQL>更新测试集col2 ='AAAA',其中col1 = 1; 1行更新。

SQL Session#2:尝试读取锁定的行,得到错误:

SQL> select * from test其中col1 = 1 for update nowait; select * from test其中col1 = 1 for update nowait               * 第1行的错误: ORA-00054:资源繁忙并在指定NOWAIT或超时过期时获取