2011-10-17 84 views
-1

可能重复:
Force Oracle to return TOP N rows with SKIP LOCKED选择与多个会话

我遇到一些问题,在Oracle UPDATE子句。我想要做的是从一个表中选择一些值(比如1000,但这个值可能会在运行时由用户改变)并处理它们。但是,我的应用程序可能在多个节点上运行,并且它们都将使用同一个表,所以我必须锁定记录以防止多个节点获取相同的记录。

为了演示,让我们创建一个示例表:

CREATE TABLE t (ID PRIMARY KEY) AS SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 1000; 

这是我选择的记录。我在这里试图获取3条记录。

SELECT rownum r, a.ID i 
    FROM (SELECT * FROM t) a 
WHERE rownum <= 3 
FOR UPDATE skip locked 

该查询返回3个记录

+ --- + --- +
+ R + I +
+ --- + --- +
+ 1 + 1 +
+ --- + --- +
+ 2 + 2 +
+ --- + --- +
+ 3 + 3 +
+ --- + --- +

当我从另一个会话(不提交会话1)运行相同的查询时,我得到一个空的结果集。但我真正想要的是取下3个项目(在这种情况下是4,5,6)。我知道这是预期的行为,但无法找到适当的解决方案。如何在不创建Oracle过程的情况下解决此问题?

+0

我会使用BULK COLLECT和LIMIT参见:http://stackoverflow.com/questions/6770317/sql-for-update-skip-locked-query-and-java-multi-threading-how-to-fix-这个 –

回答

1

这才赶上来,我给然后一个相当详细的解答:

Force Oracle to return TOP N rows with SKIP LOCKED

我真的不能想别的(比使用队列的方式)要少于上面线程中给出的信息。

+0

我发现你的答案非常有用,并试过一个简单的例子。它似乎工作正常。我也会用spring框架来尝试它。谢谢 –

-1

而不是你的例子中的SKIP LOCKED,你实际要求的是READ UNCOMMITTED,或者Oracle不太关注的“脏读”。

我有这个问题/答案的读:Does oracle allow the uncommitted read option?

+0

不,我不想读脏数据。我想要做的是阅读下面的3个项目(4,5,6)。如果我编辑问题来说明,那可能会更好。 –

+0

好的,那么将你的子查询工作中的'skip locked'移动?如下所示:'(SELECT * FROM t FOR UPDATE skip locked)a' – Widor

+0

是不是会锁定整个表格?除此之外,我得到一个错误说“ORA-00907:缺少右括号” –