【问题标题】:selecting from same table with multiple sessions [duplicate]从具有多个会话的同一张表中选择[重复]
【发布时间】:2011-12-09 02:45:07
【问题描述】:

可能重复:
Force Oracle to return TOP N rows with SKIP LOCKED

我在使用 Oracle 上的 FOR 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 过程的情况下如何解决这个问题?

【问题讨论】:

标签: oracle select locking rownum


【解决方案1】:

您实际要求的是READ UNCOMMITTED,而不是您示例中的SKIP LOCKED,或者Oracle 不热衷的“脏读”。

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

【讨论】:

  • 不,我不想读取脏数据。我想要做的是阅读接下来的 3 项(4、5、6)。如果我编辑问题以说明这一点可能会更好。
  • 好的,那么在您的子查询中移动skip locked 会起作用吗?如:(SELECT * FROM t FOR UPDATE skip locked) a
  • 那不是会锁住整张桌子吗?此外,当我这样做时,我收到一条错误消息“ORA-00907:缺少右括号”
  • 我忘了添加 SQL:SELECT rownum r, a.ID i FROM (SELECT * FROM t FOR UPDATE skip locked) a WHERE rownum
  • 我现在无法自己测试这个 - 我会让其他人加入并希望能提供帮助。
【解决方案2】:

这个之前有过,我当时给出了比较详细的回答:

Force Oracle to return TOP N rows with SKIP LOCKED

除了上面线程中提供的信息之外,我真的想不出其他方法(不使用队列)。

【讨论】:

  • 我发现您的回答非常有用,并尝试了一个简单的示例。它似乎工作正常。我也会尝试使用 spring 框架。谢谢
猜你喜欢
  • 1970-01-01
  • 2016-09-29
  • 2013-02-28
  • 2015-08-25
  • 2021-09-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
相关资源
最近更新 更多