美好的一天,各自的!
环境:适用于 Windows 的 Oracle 18XE 64 位。
我有一个关于从持久队列中出列消息数组的问题。这是一个简单的点对点消息传递。队列是“single_consumer”,没有传播。
我注册了我的 PL/SQL 回调函数。我需要知道消息数组的确切大小,以便在每次调用 Oracle AQ 内部作业的回调函数时出列。
我找到了唯一合法的方式来做到这一点。这种方法是使用sys.aq$reg_info的qosflags参数注册回调,该参数 等于 dbms_aq.NTFN_QOS_PAYLOAD。
这是注册 PL/SQL 块:
declare
v_qosflags number := dbms_aq.NTFN_QOS_PAYLOAD;
r_info SYS.AQ$_REG_INFO;
begin
r_info := SYS.AQ$_REG_INFO(
'STERN.FOUNDERS_QUEUE',
DBMS_AQ.NAMESPACE_AQ,
'plsql://stern.dosomecalc',
HEXTORAW('FF')
);
r_info.qosflags := v_qosflags;
r_info.ntfn_grouping_class := dbms_aq.NTFN_GROUPING_CLASS_TIME ;
r_info.ntfn_grouping_value := 60;
r_info.ntfn_grouping_type := dbms_aq.NTFN_GROUPING_TYPE_SUMMARY ;
DBMS_AQ.REGISTER (
SYS.AQ$_REG_INFO_LIST(
r_info
),
1
);
end;
这是回调过程的声明。这是一个标准声明:
create or replace procedure dosomecalc
(context RAW
,reginfo SYS.AQ$_REG_INFO
,descr SYS.AQ$_DESCRIPTOR
,payload raw
,payloadl NUMBER)
现在,感谢使用dbms_aq.NTFN_QOS_PAYLOAD 初始化的qosflags参数,我的回调函数以这样一种方式注册,即我始终可以在回调会话中看到要出列的消息的实际大小。此大小被评估为descr参数的descr.msgid_array部分的计数大小。如果在注册期间没有将qosflags设置为某个值 - 这部分descr参数对于回调过程调用始终为空。
一旦我知道消息数组的实际大小,我就可以在
Dbms_aq.dequeue_array(…, array_size => descr.msgid_array.count,…)
在我的回调函数中出列调用。
然后,在调查了 descr 参数的内容后,我在其中发现了一个ntfnsRecdInGrp元素,并确定 ntfnsRecdInGrp始终等于descr.msgid_array.count,并且只是为了程序员的方便,只是为了重复 descr.msgid_array.count。
AQ 文档说:
msgid_array - Group notification message ID list
ntfnsRecdInGrp - Notifications received in group
这就是为什么我决定它们在价值上是平等的。这是我的错误。当我使用数组大小等于descr.msgid_array.count的回调时——一切正常。使用ntfnsRecdInGrp – 没有。有时descr.msgid_array.count 和ntfnsRecdInGrp 相等,有时不相等。
现在的问题是:
descr 参数的ntfnsRecdInGrp部分是什么意思?
为什么它与msgid_array.count 不同?
提前致谢。