首页 > 解决方案 > 用于监视 DBMS_ALERT 的 Oracle DBMS_SCHEDULER 作业

问题描述

环境:Oracle 12c R2

试图了解设置 Oracle DBMS_SCHEDULER 作业的最佳方法是什么,该作业将用于监视 DBMS_ALERT 触发器,该触发器检查表中特定列值何时更改。

问题是,此表列值更改有时会频繁发生,有时可能一天只发生两次,但我需要通过 DBMS_ALERT 监视此列更改。

我拥有的触发器如下,我有一个称为check_signal检查我希望在 DBMS_SCHEDULER 作业中使用的信号的过程。

我要实现的目标是,我将面临需要运行三份工作的情况:

Job1
Job2
Job3

问题是,从 Job2 返回的有效负载是必需的,Job1Job2作为参数传递给 ,从 Job2 返回的有效负载是必需的,并作为参数传递给Job3.

我试图通过使用 DBMS_ALERTS 来实现这种等待/警报。

create or replace trigger my_tab_upd after update of status on my_tab for each row
begin
   dbms_alert.signal('mystatusalert', 'changed from '||:old.status||' to '||:new.status||'.');
end;
/

这将通过由多个用户使用的基于 Web 的应用程序来使用。

只是不确定如何设置此计划作业,该作业将持续检查警报,然后在 Web 应用程序中使用。

如果有比 DBMS_ALERT 更好的方法,请告诉我。

标签: oracleplsqlnotificationsoracle12c

解决方案


一般的答案很简单,在每 N 秒轮询一次事件时,您会得到平均延迟 N/2 秒和最大延迟 N 秒

在您的上下文中,DBMS_ALERT您应该重新考虑这种方法,因为这将通过等待事件实现轮询

定期执行的作业基本上使您认为:

  • DBMS_ALERT.REGISTER在事件名称上

  • 等待DBMS_ALERT.WAITONE

假设 DBMS_SCHEDULER 作业每 10 秒运行一次,并且在频繁发信号的阶段启动。所以第一次执行在收到事件后很快返回。

第二次执行属于相当时期,因此该作业将等待数小时才能获得事件

我认为这不是您所期望的

1)等待的工作将有一个开放的会话 - 你想避免的事情如下你的其他问题

您可以timeout = 0在 中使用DBMS_ALERT.WAITONE,但这将返回几乎没有事件,除了那些在REGISTER和之间意外触发的事件WAITONE

2) 如果在前 10 秒内发出两个事件信号,则第二个事件将丢失,因为在发出信号时,订阅作业不活动且不存在注册。


推荐阅读