在Oracle DB上,如何执行以下逻辑(即"等待至少返回一行并从其返回一个列值"),但没有轮询(循环,浪费CPU和可能I / O)但有一些等待/阻止机制? 因此,当调用 get_one()函数时,它不应该返回,直到它可以从匹配某些条件的表中获取一行。
function get_one()
return number
is
c1 sys_refcursor;
n number;
begin
loop
open c1 for select number_column from t1 where some_conditions;
fetch c1 into n;
if not c1%notfound then return n;
close c1;
dbms_lock.sleep(1); -- this wait reduces load, but is still polling, also it delays reaction time
end loop;
end;
该解决方案应该适用于外部应用程序(例如使用J2EE,.NET等的应用程序服务器),因此使用触发器可能不适合。
答案 0 :(得分:1)
有两个可以满足这些要求的oracle db功能:
数据库更改通知(DCN) Java - Oracle Database Change Notification
Oracle高级队列(AQ) Oracle Advanced Queue In Java
答案 1 :(得分:0)
function get_one()
return number
is
n number;
begin
loop
select (select number_column from t1 where some_conditions) into n from dual;
if n is null then
dbms_lock.sleep(1); -- wait 1 second
else
return n;
end if;
end loop;
end;
DBMS_LOCK 包提供了Oracle Lock Management的界面 服务。您可以请求锁定特定模式,给它一个唯一的模式 在同一个或另一个的另一个程序中可识别的名称 例如,更改锁定模式,然后释放它。
您可能需要一些资助才能执行此Oracle软件包
答案 2 :(得分:0)
我不赞成实现在Oracle上直接等待或轮询的代码。这可能会扭曲Oracle统计数据,如数据库时间和等待时间。
为了实现需要对正在创建或修改的某组行进行操作的服务器代码,您可以诉诸:
以预定间隔唤醒并查询行的计划作业。如果存在行,则调用作用于新行的过程。
触发器 根据插入的内容,您可以创建一个在创建行时调用的触发器。如果您尝试修改具有触发器的原始行,请注意可能出现的突变对象错误。
如果是调用“get_one”的客户端应用程序,您可能还要让客户端应用程序每隔几秒钟根据一个计时器轮询它(在两次调用之间没有浪费客户端或DB CPU)。