【问题标题】:Preserve order with Select...Where In and lock the lines使用 Select...Where In 保留顺序并锁定行
【发布时间】:2013-07-08 02:40:17
【问题描述】:

我在 java 中有以下准备好的语句:

with main_select as 
  (select request_id,rownum iden
   from 
    (select request_id
     from queue_requests
     where request_status = 0 and
           date_requested <= sysdate and
           mod(request_id,?) = ?
     order by request_priority desc, oper_id, date_requested)   
   where rownum < ?) 

select *
from queue_requests qr, main_select ms
where qr.request_id in ms.request_id
order by ms.iden for update skip locked;

它不执行:

ORA-02014:无法从具有 DISTINCT、GROUP BY 等的视图中选择 FOR UPDATE。

我将尝试解释为什么我需要所有的选择语句:

  • 第一个(内部)选择获取我需要的数据
  • 第二个将行数限制为一个数字(我不能把它放在第一个选择中,因为 oracle 首先限制了结果并且只有在对它们进行排序之后,这不是我想要的)
  • 第三个(外部)选择保留顺序(我尝试使用 3 个嵌套选择 - 所以,没有 with 子句 - 但在这种情况下我找不到保留顺序的方法)。此外,它应该锁定 queue_requests 表中的行,但是因为我从 with 子句中选择了数据,所以它给出了上述错误。

所以,我想从 queue_requests 中选择数据,保留前 x 行,保留选择的顺序并锁定行。

有办法吗?

【问题讨论】:

  • 我意识到,在我的具体情况下,我使用 mod 选择数据,所以每个线程都会选择表中自己的部分,所以我可以安全地删除“for update skip locked”。但是,对于一般情况下,选择不使用 mod 并且确实需要锁定行,我将保持这个问题打开。

标签: java sql select


【解决方案1】:

问题似乎是,您想对 main_select 的结果设置锁定。我只是猜测,您可以在 with 子句中的 select 中执行 select for update,例如:

with main_select as 
  (select request_id,rownum iden
   from (subselect)
   where rownum < ?
   for update skip locked)

但正如我所说的幸运猜测。

【讨论】:

  • 不,它不起作用。现在它说: ORA-00907:缺少右括号。我经常遇到这个错误,这有点奇怪,因为(在我看来)它与括号无关。如果我删除“更新跳过锁定”错误消失,所以我不知道是什么问题。
  • 哎呀..然后删除分号:)
  • 问题是,不知何故,数据库必须知道它必须锁定哪些行。如果您执行SELECT * FROM foo WHERE x &lt;= 5 FOR UPDATE SKIP LOCKED 之类的操作,则结果是表foo 中所有内容的子集,并且生成的行仍然具有可用于标识被锁定的行的rowId。但我认为(a)在 with 子句中或(b)在与表 queue_requests 的连接中或(c)在排序期间丢失了这些信息。
  • 我从第一次就这样做了 :) 我不知道是什么导致了错误。您确定可以在 with 子句中使用 for update 吗?外层select从queue_requests和main_select中获取数据,但是main_select会锁定queue_requests...
  • 我对此非常不确定,但我真的很想知道为什么这不能像你想要的那样工作;)
猜你喜欢
  • 2021-03-05
  • 1970-01-01
  • 2011-06-02
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
相关资源
最近更新 更多