我有一个 ITEM
表,其中一列为 CREATED_DATE
。在集群环境中,许多服务副本将从该表中挑选项目并进行处理。每个服务应该从 ITEM 表中选择最旧的 10 个项目。
我可以在存储过程中使用它来选择前 10 行:
select * from (
select item_id, row_number() over (order by CREATED_DATE) rownumber
FROM item )
where rownumber < 11
由于许多服务应该使用它,我正在使用 select ... for update
将行更新为“正在处理”。但是下面的 FOR UPDATE
语句对于上面的 select 语句失败,错误为“ORA-02014:无法从具有 DISTINCT、GROUP BY 等的 View 中选择 FOR UPDATE。”
OPEN items_cursor FOR
**select Statement**
FOR UPDATE;
请帮我解决。
最佳答案
DCookie 的回答没有解决多 session 处理(它只是为了更新语法修复)。如果您不操作行号范围,则每个服务实例都会选择更新相同的行。如果您在两个 session 中执行 that_for_update_select,第二个 session 将等到第一个完成事务。并行处理将是一种错觉。
我会考虑将高效的批量处理与for update skip locked
方法结合使用。我的回答如下:
declare
con_limit constant number default 10;
cursor cItems is
select i.item_id, i.created_date
from item i
order by i.created_date
for update skip locked;
type t_cItems is table of cItems%rowtype;
tItems t_cItems;
begin
open cItems;
while true loop
fetch cItems bulk collect into tItems limit con_limit;
-- processing tItems
exit when tItems.count < con_limit;
end loop;
end;
可能的长交易可能是一个缺点。考虑使用 Oracle Streams Advanced Queuing (DBMS_AQ) 作为此解决方案的替代方案。
关于database - oracle:更新选择前 10 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337126/