我在C#中有一个使用Oracle数据库的应用程序。 我需要一个查询来从oracle数据库中的表中获取未锁定的行。 如何选择所有未锁定的行?
是否有可以将此T-SQL(MS SQL Server)查询转换为Oracle方言的“翻译器”?
SELECT TOP 1 * FROM TableXY WITH(UPDLOCK, READPAST);
我对Oracle缺乏这样的功能感到有些失望。他们想让我使用AQ或什么?
答案 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或超时过期时获取