After a fortnight spent working with DBMS_AQ and DBMS_AQADM packages, i'd be ready to feed oraclequirks with interesting situations for days, if not weeks if only i had enough time to do so.
Unfortunately i am rather busy sorting out some important stuff before leaving or OOW 2009, so i decided to pick one of my favorite AQ (Advanced Queuing) quirks concerning bulk dequeuing of messages, via DBMS_AQ.DEQUEUE_ARRAY in Oracle 10gR2 (XE on Xubuntu linux), as this situation may easily drive you mad.
create or replaceThe most interesting property of this procedure is that it runs without raising any errors, but simply doesn't dequeue any messages from the queue.
procedure MESSAGE_READER as
dequeue_options dbms_aq.dequeue_options_t;
msg_prop_in_array dbms_aq.message_properties_array_t;
msgid_in_array dbms_aq.msgid_array_t;
type payload_array is varray(30) of payload_type;
msg_in_array payload_array;
l_msgs_in pls_integer;
begin
msg_prop_in_array := dbms_aq.message_properties_array_t();
msg_in_array := payload_array();
msgid_in_array := dbms_aq.msgid_array_t();
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.consumer_name := 'MESSAGE_READER';
dequeue_options.wait := DBMS_AQ.NO_WAIT;
l_msgs_in := dbms_aq.dequeue_array(
queue_name => 'INBOX',
dequeue_options => dequeue_options,
array_size => 30,
message_properties_array => msg_prop_in_array,
payload_array => msg_in_array,
msgid_array => msgid_in_array);
...
end;
So, you see you queue full of messages in READY state, but the procedure doesn't pull out any data.
The value returned by DBMS_AQ.DEQUEUE_ARRAY function and stored into variable l_msgs_in remains zero and the collection remains empty, however no exceptions are raised.
While i felt that something weird must be going on behind the scenes, i did not figure out the solution until i read this thread on OTN.
As soon as i declared the type as a stand-alone SQL type, in contrast with the PL/SQL declaration above (in red color), the procedure started working properly.
Don't ask me why.
create type type payload_array as varray(30) of payload_type;
create or replace
procedure MESSAGE_READER as
dequeue_options dbms_aq.dequeue_options_t;
msg_prop_in_array dbms_aq.message_properties_array_t;
msgid_in_array dbms_aq.msgid_array_t;
msg_in_array payload_array;
l_msgs_in pls_integer;
begin
msg_prop_in_array := dbms_aq.message_properties_array_t();
msg_in_array := payload_array();
msgid_in_array := dbms_aq.msgid_array_t();
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.consumer_name := 'MESSAGE_READER';
dequeue_options.wait := DBMS_AQ.NO_WAIT;
l_msgs_in := dbms_aq.dequeue_array(
queue_name => 'INBOX',
dequeue_options => dequeue_options,
array_size => 30,
message_properties_array => msg_prop_in_array,
payload_array => msg_in_array,
msgid_array => msgid_in_array);
...
end;
I ignore if this problem or bug, whatever we wanna call it, has been fixed in subsequent releases and/or it affects all platforms.
3 comments:
Interesting....
i was lucky enough to quickly find the answer on OTN, it's the kind of problem that makes you spend hours asking yourself what the hell is wrong with the code that is identical to the sample taken from the documentation.
This has helped me a lot after cracking my head for almost 2 days. Thanks alot for this post. Funny this issue has still not been fixed(if it's actually a bug)
Post a Comment