Dequeue the exception queue in ORACLE AQ - plsql

I am new to the Oracle AQ process and have a few questions about the exception queue. Here's my scenario:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0
Create Table and Queue:
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE (
QUEUE_TABLE =>'ADD_QUEUE_TABLE',
MULTIPLE_CONSUMERS => TRUE,
QUEUE_PAYLOAD_TYPE => 'ADD_OBJECT_TYPE');
DBMS_AQADM.CREATE_QUEUE (
QUEUE_NAME => 'ADD_QUEUE',
QUEUE_TABLE => 'ADD_QUEUE_TABLE',
max_retries => 6,
retry_delay => 1800);
DBMS_AQADM.START_QUEUE (QUEUE_NAME => 'ADD_QUEUE');
END;
/
To my understanding, it should retry dequeue for 6 times with delay of 30 mins and then send to exception queue. But in my case, it did send the messages to exception queue a lot before. I want your inputs to know if there is something I am missing or doing it wrong.
Enqueue:
CREATE PROCEDURE TXN_ENQUEUE_PROCEDURE (HN_TXN_SEQ IN NUMBER)
AS
ENQUEUE_OPTIONS DBMS_AQ.ENQUEUE_OPTIONS_T;
MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
MESSAGE_HANDLE RAW (16);
MESSAGE TXN_OBJECT_TYPE;
BEGIN
MESSAGE := TXN_OBJECT_TYPE (HN_TXN_SEQ);
DBMS_AQ.ENQUEUE (QUEUE_NAME => 'FILE_QUEUE',
ENQUEUE_OPTIONS => ENQUEUE_OPTIONS,
MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
PAYLOAD => MESSAGE,
MSGID => MESSAGE_HANDLE);
COMMIT;
END;
/
Dequeue:
CREATE OR REPLACE PROCEDURE TXN_DEQUEUE_PROCEDURE (
CONTEXT RAW,
REGINFO SYS.AQ$_REG_INFO,
DESCR SYS.AQ$_DESCRIPTOR,
PAYLOAD RAW,
PAYLOADL NUMBER)
AS
DEQUEUE_OPTIONS DBMS_AQ.DEQUEUE_OPTIONS_T;
MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
MESSAGE_HANDLE RAW (16);
MESSAGE TXN_OBJECT_TYPE;
BEGIN
DEQUEUE_OPTIONS.WAIT := DBMS_AQ.NO_WAIT;
DEQUEUE_OPTIONS.CONSUMER_NAME := 'MYSUBSCRIBER';
DEQUEUE_OPTIONS.NAVIGATION := DBMS_AQ.FIRST_MESSAGE;
DEQUEUE_OPTIONS.MSGID := DESCR.MSG_ID;
DEQUEUE_OPTIONS.CONSUMER_NAME := DESCR.CONSUMER_NAME;
LOOP
DBMS_AQ.DEQUEUE (QUEUE_NAME => DESCR.QUEUE_NAME,
DEQUEUE_OPTIONS => DEQUEUE_OPTIONS,
MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
PAYLOAD => MESSAGE,
MSGID => MESSAGE_HANDLE);
INSERT INTO MESSAGE_TABLE_SAMPLE VALUES (MESSAGE.HN_TXN_SEQ);
XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----
COMMIT;
END LOOP;
END;
/
When I execute enqueue and if applications goes down or for any other reasons, the messages goes to exception queue. And if I dequeue from the exception queue, do I need to mention ( XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----) within the dequeue process or it will be automatically called like normal queue dequeue process.
Exception queue :
EXECUTE DBMS_AQADM.START_QUEUE('AQ$_FILE_QUEUE_TABLE_E', false, true);
DECLARE
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
dq_msgid RAW(16);
payload RAW(1);
no_messages exception;
pragma exception_init (no_messages, -25263);
msg_count number(2);
cursor c_msg_ids is
select msg_id
from aq$FILE_QUEUE_TABLE
where queue = 'AQ$_FILE_QUEUE_TABLE_E';
BEGIN
dequeue_options.consumer_name := null;
dequeue_options.wait := DBMS_AQ.NO_WAIT;
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.dequeue_mode := dbms_aq.remove_nodata;
For v_msg_id in c_msg_ids loop
dequeue_options.msgid := v_msg_id.msg_id;
msg_count := 0;
DBMS_AQ.DEQUEUE(queue_name => 'sys.AQ$_FILE_QUEUE_TABLE_E',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => payload,
msgid => dq_msgid);
dbms_output.put_line('Message id : '||v_msg_id.msg_id||' removed');
msg_count := msg_count + 1;
dequeue_options.msgid := null;
dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;
END LOOP;
EXCEPTION
WHEN no_messages THEN
DBMS_OUTPUT.PUT_LINE ('No of Messages Removed: '||msg_count);
COMMIT;
END;
/
After executing the above one, it removes the messages from the exception queue. Do I need to mention ( XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----) anywhere in between?
Is it better to execute exception queue or to have max_retries and with retry_delay?
If the messages move to exception queue, and if I run a query to dequeue them. Do they follow the same mechanism as in dequeue the normal queue and execute any additional apis that uses the message as input?
Thank you!

Related

Oracle Advanced QUEUE does not exist is other schema

I have the same problem that is described in this issue: Grant permission to queues to another schema in oracle.
But given permissions to the other user doesn't work at all.
My queue:
DBMS_AQADM.create_queue_table (
queue_table => 'event_queue_tab',
queue_payload_type => 't_event_queue_payload',
multiple_consumers => TRUE,
comment => 'Queue Table For Event Messages',
secure => false);
-- Create the event queue.
DBMS_AQADM.create_queue (queue_name => 'event_queue',
queue_table => 'event_queue_tab');
-- Start the event queue.
DBMS_AQADM.start_queue (queue_name => 'event_queue');
This queue as created using schema USER1. In this schema, I have a package pkg1 with a procedure when I call it, its enqueue:
PROCEDURE proc1
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
l_message_handle RAW (16);
l_queue_msg t_event_queue_payload;
BEGIN
l_queue_msg := t_event_queue_payload ('give_me_a_prod');
DBMS_AQ.enqueue (queue_name => 'event_queue',
enqueue_options => l_enqueue_options,
message_properties => l_message_properties,
payload => l_queue_msg,
msgid => l_message_handle);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END proc1;
I have a second schema USER2 who have privileges to execute pkg1 by a specific ROLE (ROLE1). But when he calls proc1, receive the next error:
ORA-24010: QUEUE USER2.EVENT_QUEUE does not exist - ORA-06512: at "SYS.DBMS_AQ", line 180
ORA-06512: at "USER1.PKG1", line 1808
I've executed this privilege command in USER1 but without success:
BEGIN
DBMS_AQADM.grant_queue_privilege (privilege => 'ALL',
queue_name => 'USER1.event_queue',
grantee => 'USER2',
grant_option => TRUE);
END;
I'm really starting to understand how Ad.Queues works. Am I missing something here? Thanks.
EDIT1:
After the grant given the privileges for this queue:
SELECT grantee,
owner,
name,
grantor,
enqueue_privilege,
dequeue_privilege
FROM queue_privileges
WHERE name = upper('event_queue');
ROLE1 USER1 EVENT_QUEUE USER1 1 1
USER2 USER1 EVENT_QUEUE USER1 1 1
Just a guess, does it have something to do with synonyms? Because the error message says USER2.QUEUE doesn't exist. Maybe its not able to touch User1 queue, because internally it is trying to find it in it's own schema? Try giving queue name in procedure as user1.event_queue.
What I mean is:
PROCEDURE proc1
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
l_message_handle RAW (16);
l_queue_msg t_event_queue_payload;
BEGIN
l_queue_msg := t_event_queue_payload ('give_me_a_prod');
DBMS_AQ.enqueue (queue_name => 'user1.event_queue',
enqueue_options => l_enqueue_options,
message_properties => l_message_properties,
payload => l_queue_msg,
msgid => l_message_handle);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END proc1;
Why I say so? Because when you are giving permission you are explicitly mentioning the schema USER1 before event_queue, and that procedure works. But not doing the same when using the enqueue procedure.

Getting this error when you execute the procedure ORA-29270: too many open HTTP requests

utl_http.end_response(http_resp) ;
-- x_clob response can now be used for extracting text
-- values from specific XML nodes, using XMLExtract
EXCEPTION
WHEN ERROR_OUT THEN
error_code := error_code;
error_desc := error_desc; ---SQLERRM||' Unhandled Exception';
WHEN OTHERS THEN
error_code := '91';
error_desc := SQLERRM || ' Unhandled Exception';
dbms_output.put_line('Error desc:' || error_desc );
end;
/
Getting Below error after the Procedure execution
HTTP Request Failed
ORA-29270: too many open HTTP requests
Many time this procedure will be executed.
let me know how to End some HTTP requests and response and execute all the Request

API Error ORA-29270: too many open HTTP requests

We are getting the ORA-29270:too many open HTTP requests when try to execute the Below Procedure. Please let us know where and all we need to close the Request and Response , Please provide one of the Procedure example how we can handle the exception. and all the request should process Properly.
BEGIN
l_http_request := utl_http.begin_request (p_url, 'POST');
BEGIN
-- build the request by using utl_http.set_header() and utl_http.write_text()
-- ...
-- process the request and get the response:
l_http_response := utl_http.get_response (l_http_request);
WHEN OTHERS THEN
--- utl_http.end_response(http_resp);
error_code := '91';
error_desc := SQLERRM || ' Unhandled Exception';
END;
BEGIN
LOOP
-- read the response using utl_http.read_line()
-- ...
END LOOP;
-- Complete the request and response, and close the network connection
utl_http.end_response(l_http_response);
EXCEPTION
when utl_http.end_of_body then
utl_http.end_response(http_resp);
WHEN error_out THEN
NULL;
WHEN OTHERS THEN
--- utl_http.end_response(http_resp);
error_code := '91';
error_desc := SQLERRM || ' Unhandled Exception';
END;
END;
Hello: I happen to be addressing the same error in my own code. I fixed mine by adding utl_http.end_response(l_http_response) - which you already have.
But I notice you use two different arguments in your end_response call. Try changing
utl_http.end_response(http_resp);
to
utl_http.end_response(l_http_response);
in your exception block. I hope this helps. Cheers, Hawk

ORA-01830 Error for 11.2.0 client but not for 10.2 client

I have this piece of code:
BEGIN
DBMS_SCHEDULER.DROP_JOB (
job_name => 'LOANSBUILD.LOANSNEWYORKCLOSE');
END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => '***.LOANSNEWYORKCLOSE',
job_type => 'PLSQL_BLOCK',
job_action => 'begin loans_schedule_job.loans_close(TRUNC(SYSDATE), ''N''); end;',
start_date => '15-NOV-08 12.00.00.000000000 AM AMERICA/NEW_YORK',
repeat_interval => 'FREQ=WEEKLY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=16;BYMINUTE=0;BYSECOND=0',
auto_drop => FALSE,
job_class => 'DEFAULT_JOB_CLASS',
enabled => TRUE,
comments => 'Test.'
);
END;
/
exit;
When the above is executed from an environment which has oracle sql client 10.2 installed , this goes fine but when the same is executed fron an environment that has 11.2 client installed, this fails as below:
BEGIN
*
ERROR at line 1:
ORA-01830: date format picture ends before converting entire input string
ORA-06512: at line 2
The variable nls_date_format is set to 'DD-MON-RR' in the 10.2 environment and set to 'YYYY-MM-DD HH24:MI:SS' in the 11.2 env.
As this was getting compiled for 10.2 env, I updated nls_lang_date in the 11.2 env as well to make it 'DD-MON-RR' but even after that I get the same error. Is there anything else I should be setting.
Please note that I am sysadmin and as this code is getting compiled on of the server, my job is to ensure that it does on others as well. Which also means that I do not have permissions to update code.
According to the CREATE_JOB Procedure documentation, the parameter start_date must be of type TIMESTAMP WITH TIME ZONE.
In your PL/SQL code you are instead passing a string thus relying on implicit conversion.
You could instead use an explicit conversion to the TIMESTAMP WITH TIME ZONE data type such as:
TO_TIMESTAMP_TZ('15-NOV-08 12.00.00.000000000 AM AMERICA/NEW_YORK', 'DD-MON-RR HH:MI:SS.FF AM TZR')

Calling .net WS (OPERATION_STYLE=document) from oracle(PL/sql) using UTL_DBWS package

I have created a web service using ASP.NET.
I tried to access this url from a PL/sql program through UTL_DBWS package. After execution i am receiving below error:
ORA-29532: Java call terminated by uncaught Java exception: port: {http://tempuri.org/}Service1Soap
does not contain operation: Envelope
Can any one of you please tell what steps of configuration I am missing.
I really apprcite your help.
Oracle procedure to call to asp.net service is :
create or replace procedure check_dbws
AS
l_service UTL_DBWS.service;
l_call UTL_DBWS.call;
l_wsdl_url VARCHAR2(32767);
l_namespace VARCHAR2(32767);
l_service_qname UTL_DBWS.qname;
l_port_qname UTL_DBWS.qname;
l_operation_qname UTL_DBWS.qname;
l_xmltype_in SYS.XMLTYPE;
l_xmltype_out SYS.XMLTYPE;
p_fault_node xmltype;
l_return NUMBER;
l_int_type utl_dbws.qname;
l_string_type utl_dbws.QNAME;
BEGIN
l_wsdl_url := 'http://localhost/TestWebService/Service1.asmx?wsdl';
l_namespace := 'http://tempuri.org/';
l_service_qname := UTL_DBWS.to_qname(l_namespace, 'Service1');
l_port_qname := UTL_DBWS.to_qname(l_namespace, 'Service1Soap');
l_operation_qname := UTL_DBWS.to_qname(l_namespace, 'DBConnect');
l_service := UTL_DBWS.create_service (
wsdl_document_location => URIFACTORY.getURI(l_wsdl_url),
service_name => l_service_qname);
l_call := UTL_DBWS.create_call (
service_handle => l_service,
port_name => l_port_qname,
operation_name => l_operation_qname);
utl_dbws.set_property (l_call,'SOAPACTION_USE','TRUE');
utl_dbws.set_property (l_call,'SOAPACTION_URI', 'DBConnect');
utl_dbws.set_property(l_call,'ENCODINGSTYLE_URI', 'http://schemas.xmlsoap.org/soap/encoding/');
utl_dbws.set_property(l_call,'OPERATION_STYLE', 'document');
l_string_type :=utl_dbws.to_qname('http://www.w3.org/2001/xmlschema','String');
utl_dbws.add_parameter(l_call,'Request',l_string_type,'ParameterMode.IN');
utl_dbws.set_return_type(l_call,l_string_type);
l_xmltype_in:=sys.xmltype('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v002="http://tempuri.org/DBConnect">
<soapenv:Header/>
<soapenv:Body>
<DBConnect>
<Name>Test</Name>
<DBConnect>
</soapenv:Body>
</soapenv:Envelope>');
l_xmltype_out := UTL_DBWS.invoke (call_handle => l_call,,request => l_xmltype_in);
p_fault_node := l_xmltype_out.extract('//soap:Fault', 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/');
if (p_fault_node is not null) then
dbms_output.put_line(p_fault_node.getclobval());
l_return:=2;
elsif l_xmltype_out is not null then
dbms_output.put_line(l_xmltype_out.getclobval());
l_return:=1;
else
dbms_output.put_line('errorin fault'||sqlerrm);
l_return:=0;
end if;
UTL_DBWS.release_call (call_handle => l_call);
UTL_DBWS.release_service (service_handle => l_service);
dbms_output.put_line(l_result.AccessVarchar2);
END;
have a look at my answer here; you may not have all the Java classes required to get UTL_DBWS to work. And, per my answer there, I'll reiterate, I found it much easier to use UTL_HTTP than UTL_DBWS and continue to use UTL_HTTP since I ran into so many limitations and issues with UTL_DBWS.

Resources