Non-Persistent Messages Being Enqueued As Persistent When Using JMS

(Doc ID 413073.1)

Last updated on AUGUST 25, 2017

Applies to:

Oracle Database - Enterprise Edition - Version 10.2.0.2 and later
Oracle Containers for J2EE - Version 10.1.2.0.2 and later
Information in this document applies to any platform.

Symptoms

On 10.2.0.2.0 in Production:
Messages enqueued from java code with deliverymode=NON-Persistent are showing as Persistent.
This does work from pl/sql code, but not from java code.


EXPECTED BEHAVIOR
Enqueuing the message as DeliveryMode.NON_PERSISTENT from the java code should be the same as from pl/sql.
The message should appear as IN-MEMORY in the queue, but it appears as READY.

STEPS
Steps to reproduce the problem:

1. Create the AQ objects:

EXECUTE dbms_aqadm.create_queue_table (queue_table => 'TAPESTRY_XML_QUEUE',
                                       sort_list => 'PRIORITY,ENQ_TIME',
                                       comment => 'Tapestry XML Queue Table',
                                       queue_payload_type => 'SYS.XMLtype',
                                       message_grouping => DBMS_AQADM.NONE);

EXECUTE dbms_aqadm.create_queue ( queue_name=>'Q_XML_RFD_OUTPUT',
                                  queue_table=>'tapestry_xml_queue',
                                  retention_time=>3600,
                                  max_retries=>5,
                                  retry_delay=>15 );

EXECUTE dbms_aqadm.start_queue ( queue_name=>'Q_XML_RFD_OUTPUT' );

2. To check there is nothing in the queue run the statement:

select count(*) from aq$tapestry_xml_queue;

3. To test from plsql:

set serveroutput on
declare
  my_opt dbms_aq.enqueue_options_t;
  my_prop dbms_aq.message_properties_t;
  my_data SYS.XMLtype;
  my_msgid raw(16);
  text CLOB;
begin
  text :=
    '<TyWorkRequest ID="mf009">
       <CommandList>
         <AclSecurityCmd ID="mf001">
           <AclSecurityFacade PrincipalID="scott" Password="tiger" Action="LOGIN"/>
         </AclSecurityCmd>
       </CommandList>
     </TyWorkRequest>';

  my_data := SYS.XMLtype(text);
  my_opt.delivery_mode := dbms_aq.buffered;
  my_opt.visibility := dbms_aq.immediate;
  my_prop.delivery_mode := dbms_aq.buffered;

  dbms_aq.enqueue(
      queue_name => 'Q_XML_RFD_OUTPUT',
      enqueue_options => my_opt,
      message_properties => my_prop,
      payload => my_data,
      msgid => my_msgid);

  commit;
END;
/

4. Run the following statement:

select queue, msg_state from aq$tapestry_xml_queue;

    Here we will have the three messages with the MSG_STATE as IN-MEMORY.

5. Dequeu the message from plsql:

declare
  deq_options dbms_aq.dequeue_options_t;
  deq_msgid raw(16);
  deq_msg_prop dbms_aq.message_properties_t;
  no_messages exception;
  deq_payload xmltype;
  pragma exception_init (no_messages, -25228);
begin
  deq_options.wait := 0;
  deq_options.dequeue_mode := dbms_aq.remove;
  deq_options.visibility := dbms_aq.immediate;
  deq_options.navigation := dbms_aq.first_message;
  deq_options.delivery_mode := dbms_aq.persistent;
  dbms_output.put_line('persistent: ');

  begin
    dbms_aq.dequeue (
      queue_name => 'Q_XML_RFD_OUTPUT',
      dequeue_options => deq_options,
      message_properties => deq_msg_prop,
      payload => deq_payload,
      msgid => deq_msgid);

    dbms_output.put_line('retrieved: ' || deq_payload.getstringval());
  exception
    when no_messages then
      dbms_output.put_line('no messages');
    when others then
      raise;
  end;

  dbms_output.put_line('buffered: ');

  begin
    deq_options.delivery_mode := dbms_aq.buffered;
    dbms_aq.dequeue (
      queue_name => 'oQ_XML_RFD_OUTPUT',
      dequeue_options => deq_options,
      message_properties => deq_msg_prop,
      payload => deq_payload,
      msgid => deq_msgid);

    dbms_output.put_line('retrieved: ' || deq_payload.getstringval());

  exception
    when no_messages then
      dbms_output.put_line('no messages');
    when others then
      raise;
  end;
end;
/

6. Execute the following statement:

select queue, msg_state from aq$tapestry_xml_queue;

7. Execute the next java program:

import javax.jms.*;
import oracle.jms.*;
import oracle.xdb.*;

public class jms
{
  public static void main (String args [])
      throws java.sql.SQLException,
             ClassNotFoundException,
             JMSException
  {
    try
    {
      String ora_sid = "v10";
      String host = "myhostname";
      String schema = "scott";
      String password = "tiger";
      String queueName = "Q_XML_RFD_OUTPUT";
      int port = 1521;

      Enqueue(ora_sid, host, schema, password, queueName, port);
      System.out.println("You should see 3 messages in Q_XML_RFD_OUTPUT. Should be buffered, but they are persistent instead");
    }
    catch (Exception ex)
    {
      System.out.println("Exception: " + ex);
    }
  }

  public static void Enqueue(String ora_sid,
                             String host,
                             String schema,
                             String password,
                             String queueName,
                             int port)
  {
    QueueConnectionFactory qc_fact = null;
    QueueConnection q_conn = null;
    QueueSession q_sess = null;
    java.sql.Connection db_conn = null;
    Queue queue = null;
    AdtMessage adt_msg = null;
    QueueSender q_sender = null;
    oracle.xdb.XMLType xtype = null;
    String data = null;

    try
    {
      qc_fact = AQjmsFactory.getQueueConnectionFactory(host, ora_sid, port, "thin");
      q_conn = qc_fact.createQueueConnection(schema, password);
      q_sess = q_conn.createQueueSession(true, Session.CLIENT_ACKNOWLEDGE);
      q_conn.start();
      db_conn = ((AQjmsSession)q_sess).getDBConnection();
      queue = ((AQjmsSession)q_sess).getQueue(schema, queueName);
      q_sender = q_sess.createSender(queue);
      adt_msg = ((AQjmsSession)q_sess).createAdtMessage();
      data = "<bolek>olek</bolek>";
      xtype = oracle.xdb.XMLType.createXML(db_conn, data);
      adt_msg.setAdtPayload(xtype);

      //try sending a buffered message, different ways, none of them works!
      ((AQjmsQueueSender)q_sender).send(queue,
                                       adt_msg,
                                       DeliveryMode.NON_PERSISTENT,
                                       1,
                                       AQjmsConstants.EXPIRATION_NEVER);

      q_sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
      ((AQjmsQueueSender)q_sender).send(queue,
                                         adt_msg,
                                         DeliveryMode.NON_PERSISTENT,
                                         1,
                                         AQjmsConstants.EXPIRATION_NEVER);

      adt_msg.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
      ((AQjmsQueueSender)q_sender).send(queue,
                                        adt_msg,
                                        DeliveryMode.NON_PERSISTENT,
                                        1,
                                        AQjmsConstants.EXPIRATION_NEVER);

      q_sess.commit();
      q_sess.close();
      q_conn.close();

    }
    catch (Exception e)
    {
      System.out.println("Exception: " + e);
    }
  }
}


8. Execute the following statement:

select queue, msg_state from aq$tapestry_xml_queue;

    Here we will have the three messages with the MSG_STATE as READY.

Cause

Sign In with your My Oracle Support account

Don't have a My Oracle Support account? Click to get started

My Oracle Support provides customers with access to over a
Million Knowledge Articles and hundreds of Community platforms