我有一个持续运行的.NET应用程序(Windows ),它一直在监听Oracle中的事件表,并在触发警报时执行任务。我用的是Oracle.ManagedDataAccess包。
我正在使用DBMS_ALERT包来完成我的目标。
执行以下代码以侦听警报:
string query = "BEGIN " +
" dbms_alert.register(:Name);" +
" dbms_alert.WaitOne(:Name, :Message, :Status, :timeout);" +
" dbms_alert.remove(:Name);" +
"END;";这正是我在Oracle文档中可以找到的。
这个解决方案是可行的,但是我有一个小的问题当警报被触发时,我的应用程序开始执行它的内容,同时我再次开始侦听(异步)。但有时从删除警报到重新注册警报需要几秒钟的时间。在很多情况下我都会错过警报。
问题 1)有什么方法可以让我继续监听,在发出警报时也是如此,这样我就不会错过任何事件? 2)从功能角度来看,我发现每次都必须注册和删除警报是很奇怪的。这真的有必要吗?
发布于 2019-11-11 13:03:27
有什么方法可以让我继续监听,当警报被触发的时候,这样我就不会错过任何事件?
是。您为每个DB会话注册一次警报,然后将接收所有警报。不需要重新注册。
如果希望接收在注册侦听之前发出的警报,请检查dbms_alert.register过程的完整规范,以查找:
procedure register(name in varchar2, cleanup in boolean default TRUE);
-- Register interest in an alert. A session may register interest in
-- an unlimited number of alerts. Alerts should be de-registered when
-- the session no longer has any interest (see 'remove'). This call
-- always performs a 'commit'.
-- Input parameters:
-- name
-- The name of the alert in which this session is interested.
-- WARNING: Alert names beginning with 'ORA$' are reserved for use for
-- products provided by Oracle Corporation. Name must be 30 bytes
-- or less. The name is case-insensitive.
-- cleanup
-- This specifies whether we should perform cleanup of any orphaned
-- pipes that may exist and are used by the dbms_alert package. This
-- cleanup is only performed on the first call to "register" for each
-- package instantiation. The default for the parameter is TRUE.Note第二个可选参数cleanup,默认为true。将其作为false传递,并且您的会话在注册之前从未遗漏过警报。
从功能的角度来看,我觉得奇怪的是每次我都要注册并删除警报。这真的有必要吗?
不,没必要。
至于重新登记,见上文。
至于取消警报..。这是一篇写得不好的文件。remove和removeall过程不会从警报“队列”中删除警报,它们只是使您的DB会话停止侦听警报,即remove与register相反。
https://stackoverflow.com/questions/58749464
复制相似问题