Skip Headers

Oracle9i Application Developer's Guide - Advanced Queuing
Release 2 (9.2)

Part Number A96587-01
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to next page

11
Operational Interface: Basic Operations

In this chapter we describe the operational interface to Oracle Advanced Queuing in terms of use cases. That is, we discuss each operation (such as "Enqueue a Message") as a use case by that name. The table listing all the use cases is provided at the head of the chapter (see "Use Case Model: Operational Interface -- Basic Operations" on page 11-2).

A summary figure, "Use Case Diagram: Operational Interface -- Basic Operations", locates all the use cases in a single drawing. If you are using the HTML version of this document, you can use this figure to navigate to the use case in which you are interested by clicking on the relevant use case title.

Each use case is laid out as follows:

Use Case Model: Operational Interface -- Basic Operations

Table 11-1, " Use Case Model: Operational Interface" indicates with a + where examples are provided for specific use cases and in which programmatic environment.

The table refers to programmatic environments with the following abbreviations:

Enqueuing a Message

Figure 11-1 Enqueuing a Message

Text description of adque084.gif follows
Text description of the illustration adque084.gif


See Also:

Purpose

Adds a message to the specified queue.

Usage Notes

If a message is enqueued to a multiconsumer queue with no recipient and the queue has no subscribers (or rule-based subscribers that match this message), then the Oracle error ORA 24033 is raised. This is a warning that the message will be discarded since there are no recipients or subscribers to whom it can be delivered.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

Enqueuing a Message [Specify Options]

Figure 11-2 Enqueuing a Message [Specify Options]

Text description of adque087.gif follows
Text description of the illustration adque087.gif


See Also:

Purpose

To specify the options available for the enqueue operation.

Usage Notes

Do not use the immediate option when you want to use LOB locators since LOB locators are valid only for the duration of the transaction. As the immediate option automatically commits the transaction, your locator will not be valid.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

Enqueuing a Message [Specify Message Properties]

Figure 11-3 Enqueuing a Message [Specify Message Properties]

Text description of adque085.gif follows
Text description of the illustration adque085.gif


See Also:

Purpose

The Message Properties describe the information that is used by AQ to manage individual messages. These are set at enqueue time and their values are returned at dequeue time.

Usage Notes

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

Enqueuing a Message [Specify Message Properties [Specify Sender ID]]

Figure 11-4 Enqueuing a Message [Specify Message Properties [Specify Sender ID]]

Text description of adque086.gif follows
Text description of the illustration adque086.gif


See Also:

Purpose

To identify the sender (producer) of a message.

Usage Notes

Not applicable.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

Enqueuing a Message [Add Payload]

Figure 11-5 Enqueuing a Message [Add Payload]

Text description of adque088.gif follows
Text description of the illustration adque088.gif


See Also:

Usage Notes

To store a payload of type RAW, AQ will create a queue table with LOB column as the payload repository. The maximum size of the payload is determined by which programmatic environment you use to access AQ. For PL/SQL, Java and precompilers the limit is 32K; for the OCI the limit is 4G.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

PL/SQL (DBMS_AQ Package): Enqueue of Object Type Messages

Note: You may need to set up the following data structures for certain examples to work:

CONNECT system/manager
CREATE USER aq IDENTIFIED BY aq;
GRANT Aq_administrator_role TO aq;
EXECUTE DBMS_AQADM.CREATE_QUEUE_TABLE (
   Queue_table            =>  'aq.objmsgs_qtab',
   Queue_payload_type     =>  'aq.message_typ');
EXECUTE DBMS_AQADM.CREATE_QUEUE ( 
   Queue_name            =>  'aq.msg_queue',
   Queue_table           =>  'aq.objmsgs_qtab');
EXECUTE DBMS_AQADM.START_QUEUE (
   Queue_name         => 'aq.msg_queue',
   Enqueue            => TRUE);
EXECUTE DBMS_AQADM.CREATE_QUEUE_TABLE (
   Queue_table            => 'aq.prioritymsgs_qtab',
   Sort_list              => 'PRIORITY,ENQ_TIME',
   Queue_payload_type     => 'aq.message_typ');
EXECUTE DBMS_AQADM.CREATE_QUEUE (
   Queue_name             => 'aq.priority_msg_queue',
   Queue_table            => 'aq.prioritymsgs_qtab');
EXECUTE DBMS_AQADM.START_QUEUE (
   Queue_name             => 'aq.priority_msg_queue',
   Enqueue                => TRUE);


Enqueue a Single Message and Specify the Queue Name and Payload

/* Enqueue to msg_queue: */
DECLARE
   Enqueue_options     DBMS_AQ.enqueue_options_t;
   Message_properties  DBMS_AQ.message_properties_t;
   Message_handle      RAW(16);
   Message             aq.message_typ;

BEGIN
   Message := aq.message_typ('NORMAL MESSAGE',
      'enqueued to msg_queue first.');

   DBMS_AQ.ENQUEUE(queue_name => 'msg_queue',           
   Enqueue_options            => enqueue_options,       
   Message_properties         => message_properties,     
   Payload                    => message,               
   Msgid                      => message_handle);

   COMMIT;
END;

Enqueue a Single Message and Specify the Priority

/* The queue name priority_msg_queue is defined as an object type queue table. 
 The payload object type is message. The schema of the queue is aq.  */

 /* Enqueue a message with priority 30: */ 
DECLARE 
   Enqueue_options       dbms_aq.enqueue_options_t; 
   Message_properties    dbms_aq.message_properties_t; 
   Message_handle        RAW(16); 
   Message               aq.Message_typ; 
 
BEGIN 
   Message := Message_typ('PRIORITY MESSAGE', 'enqued at priority 30.'); 
 
   message_properties.priority := 30; 
 
   DBMS_AQ.ENQUEUE(queue_name => 'priority_msg_queue', 
   enqueue_options            => enqueue_options, 
   message_properties         => message_properties, 
   payload                    => message, 
   msgid                      => message_handle); 
 
   COMMIT; 
END; 

Enqueue a Single Message and Specify a Transformation

/* Enqueue to msg_queue: */
DECLARE
   Enqueue_options     DBMS_AQ.enqueue_options_t;
   Message_properties  DBMS_AQ.message_properties_t;
   Message_handle      RAW(16);
   Message             aq.message_typ;

BEGIN
   Message := aq.message_typ('NORMAL MESSAGE',
      'enqueued to msg_queue first.');

   DBMS_AQ.ENQUEUE(queue_name => 'msg_queue',           
   Enqueue_options            => enqueue_options,       
   Message_properties         => message_properties,
   transformation             => 'AQ.MSG_MAP',    
   Payload                    => message,               
   Msgid                      => message_handle);

   COMMIT;
END;

Where MSG_MAP was created as follows:

BEGIN
   DBMS.TRANSFORM.CREATE_TRANSFORMATION
   (
      schema => 'AQ',
      name =>   'MSG_MAP',
      from_schema => 'AQ',
      from_type => 'PO_ORDER1',
      to_schema => 'AQ',
      to_type => 'PO_ORDER2',
      transformation => 'AQ.MAP_PO_ORDER (source.user_data)'),
END;
Java (JDBC): Enqueue a message (add payload)
/* Setup  */
connect system/manager
create user aq identified by aq;
grant aq_administrator_role to aq;

public static void setup(AQSession aq_sess) throws AQException
{
     AQQueueTableProperty    qtable_prop;
     AQQueueProperty         queue_prop;
     AQQueueTable            q_table;
     AQQueue                 queue;
     AQAgent                 agent;

     qtable_prop = new AQQueueTableProperty("RAW"); 

     q_table = aq_sess.createQueueTable ("aq", "rawmsgs_qtab", qtable_prop);

     queue_prop = new AQQueueProperty();
     queue = aq_sess.createQueue (q_table, "msg_queue", queue_prop);

     queue.start();

     qtable_prop = new AQQueueTableProperty("RAW"); 
     qtable_prop.setMultiConsumer(true);

     qtable_prop.setSortOrder("priority,enq_time");
     q_table = aq_sess.createQueueTable ("aq", "rawmsgs_qtab2", 
                         qtable_prop);

     queue_prop = new AQQueueProperty();
     queue = aq_sess.createQueue (q_table, "priority_msg_queue", queue_prop);

     queue.start();

     agent = new AQAgent("subscriber1", null);

     queue.addSubscriber(agent, null);
}


/* Enqueue a message */
public static void example(AQSession aq_sess) throws AQException, SQLException
{
     AQQueue                  queue;
     AQMessage                message;
     AQRawPayload             raw_payload;
     AQEnqueueOption          enq_option;
     String                   test_data = "new message";
     byte[]                   b_array;
     Connection               db_conn;

     db_conn = ((AQOracleSession)aq_sess).getDBConnection();

     /* Get a handle to the queue */
     queue = aq_sess.getQueue ("aq", "msg_queue");

     /* Create a message to contain raw payload: */
     message = queue.createMessage();

     /* Get handle to the AQRawPayload object and populate it with raw data: */
     b_array = test_data.getBytes();

     raw_payload = message.getRawPayload();

     raw_payload.setStream(b_array, b_array.length);

     /* Create a AQEnqueueOption object with default options: */
     enq_option = new AQEnqueueOption();

     /* Enqueue the message: */
     queue.enqueue(enq_option, message);
     
     db_conn.commit();
}


/* Enqueue a message with priority = 5 */
public static void example(AQSession aq_sess) throws AQException, SQLException
{
     AQQueue                  queue;
     AQMessage                message;
     AQMessageProperty        msg_prop;
     AQRawPayload             raw_payload;
     AQEnqueueOption          enq_option;
     String                   test_data = "priority message";
     byte[]                   b_array;
     Connection               db_conn;

     db_conn = ((AQOracleSession)aq_sess).getDBConnection();

     /* Get a handle to the queue */
     queue = aq_sess.getQueue ("aq", "msg_queue");

     /* Create a message to contain raw payload: */
     message = queue.createMessage();

     /* Get Message property */
     msg_prop = message.getMessageProperty();

     /* Set priority */
     msg_prop.setPriority(5);

     /* Get handle to the AQRawPayload object and populate it with raw data: */
     b_array = test_data.getBytes();

     raw_payload = message.getRawPayload();

     raw_payload.setStream(b_array, b_array.length);

     /* Create a AQEnqueueOption object with default options: */
     enq_option = new AQEnqueueOption();

     /* Enqueue the message: */
     queue.enqueue(enq_option, message);
     
     db_conn.commit();
}
Visual Basic (OO4O): Enqueue a message

Enqueuing messages of type objects

'Prepare the message. MESSAGE_TYPE is a user defined type
' in the "AQ" schema 
Set OraMsg = Q.AQMsg(1, "MESSAGE_TYPE") 
Set OraObj = DB.CreateOraObject("MESSAGE_TYPE") 

OraObj("subject").Value = "Greetings from OO4O" 
OraObj("text").Value = "Text of a message originated from OO4O" 

Set OraMsg.Value = OraObj 
Msgid = Q.Enqueue

Enqueuing messages of type RAW

'Create an OraAQ object for the queue "DBQ" 
Dim Q as object 
Dim Msg as object 
Dim OraSession as object 
Dim DB as object 

Set OraSession = CreateObject("OracleInProcServer.XOraSession") 
Set OraDatabase = OraSession.OpenDatabase(mydb, "scott/tiger" 0&) 
Set Q = DB.CreateAQ("DBQ") 

'Get a reference to the AQMsg object 
Set Msg = Q.AQMsg 
Msg.Value = "Enqueue the first message to a RAW queue." 

'Enqueue the message 
Q.Enqueue() 

'Enqueue another message.  

Msg.Value = "Another message" 
Q.Enqueue() 

'Enqueue a message with nondefault properties. 
Msg.Priority = ORAQMSG_HIGH_PRIORITY 
Msg.Delay = 5 
Msg.Value = "Urgent message" 
Q.Enqueue() 
Msg.Value = "The visibility option used in the enqueue call is 
             ORAAQ_ENQ_IMMEDIATE" 
Q.Visible = ORAAQ_ENQ_IMMEDIATE 
Msgid = Q.Enqueue 

'Enqueue Ahead of message Msgid_1 
Msg.Value = "First Message to test Relative Message id" 
Msg.Correlation = "RELATIVE_MESSAGE_ID" 

Msgid_1 = Q.Enqueue 
Msg.Value = "Second message to test RELATIVE_MESSAGE_ID is queued 
             ahead of the First Message " 
OraAq.relmsgid = Msgid_1 
Msgid = Q.Enqueue

Listening to One or More Single-Consumer Queues

Figure 11-6 Listening to One or More Single-Consumer Queues

Text description of adque090.gif follows
Text description of the illustration adque090.gif


See Also:

Usage Notes

The call takes a list of agents as an argument. You specify the queue to be monitored in the address field of each agent listed. You also must specify the name of the agent when monitoring multiconsumer queues. For single-consumer queues, an agent name must not be specified. Only local queues are supported as addresses. Protocol is reserved for future use.

This is a blocking call that returns when there is a message ready for consumption for an agent in the list. If there are messages for more than one agent, only the first agent listed is returned. If there are no messages found when the wait time expires, an error is raised.

A successful return from the listen call is only an indication that there is a message for one of the listed agents in one the specified queues. The interested agent must still dequeue the relevant message.

Note that you cannot call listen on nonpersistent queues.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

PL/SQL (DBMS_AQ Package): Listen to Queues
/* The listen call allows you to monitor a list of queues for messages for 
 specific agents. You need to have dequeue privileges for all the queues 
 you wish to monitor. */

Listen to Single-Consumer Queue (Timeout of Zero).

DECLARE
   Agent_w_msg      aq$_agent;
   My_agent_list    dbms_aq.agent_list_t;

BEGIN
   /* NOTE:  MCQ1, MCQ2, MCQ3 are multiconsumer queues  in SCOTT's schema
   *        SCQ1, SCQ2, SCQ3 are single-consumer queues in SCOTT's schema
   */

   Qlist(1):= aq$_agent(NULL, 'scott.SCQ1',  NULL);
   Qlist(2):= aq$_agent(NULL, 'SCQ2', NULL);
   Qlist(3):= aq$_agent(NULL, 'SCQ3', NULL);

 /* Listen with a time-out of zero: */
   DBMS_AQ.LISTEN(
      Agent_list   =>   My_agent_list, 
      Wait         =>   0, 
      Agent        =>   agent_w_msg);
   DBMS_OUTPUT.PUT_LINE('Message in Queue :- ' ||  agent_w_msg.address);
   DBMS_OUTPUT.PUT_LINE('');
END;

Java (JDBC): Listen to Queues
public static void monitor_status_queue(Connection db_conn)
{
    AQSession         aq_sess;
    AQAgent[]         agt_list = null;
    AQAgent           ret_agt  = null;
    
    try
    {
        /* Create an AQ Session: */
        aq_sess = AQDriverManager.createAQSession(db_conn);

/* Construct the waiters list: */ 
agt_list = new AQAgent[3];

agt_list[0] = new AQAgent(null, "scott.SCQ1",0);
agt_list[1] = new AQAgent (null, "SCQ2",0);
agt_list[2] = new AQAgent (null, "SCQ3",0);

/* Wait for order status messages for 120 seconds: */
ret_agt = aq_sess.listen(agt_list, 120);

System.out.println("Message available for agent: " + 
   ret_agt.getName()  + "   "  + ret_agt.getAddress());

    }
    catch (AQException aqex)
    {
System.out.println("Exception-1: " + aqex);       
    }
    catch (Exception ex)
    {
        System.out.println("Exception-2: " + ex);
    }   

}

C (OCI): Listen to Single-Consumer Queues

Listening for Single-Consumer Queues with Zero Timeout

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>

static void checkerr(errhp, status)
LNOCIError *errhp;
sword status;
{
    text errbuf[512];
    ub4 buflen;
    sb4 errcode;

    switch (status)
    {
   case OCI_SUCCESS:
       break;
   case OCI_SUCCESS_WITH_INFO:
       printf("Error - OCI_SUCCESS_WITH_INFO\n");
       break;
   case OCI_NEED_DATA:
       printf("Error - OCI_NEED_DATA\n");
       break;
   case OCI_NO_DATA:
       printf("Error - OCI_NO_DATA\n");
       break;
   case OCI_ERROR:
       OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode,
       errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
       printf("Error - %s\n", errbuf);
       break;
   case OCI_INVALID_HANDLE:
       printf("Error - OCI_INVALID_HANDLE\n");
       break;
   case OCI_STILL_EXECUTING:
       printf("Error - OCI_STILL_EXECUTE\n");
       break;
   case OCI_CONTINUE:
       printf("Error - OCI_CONTINUE\n");
       break;
   default:
   break;
    }
}

/* set agent into descriptor */
void SetAgent(agent, appname, queue,errhp)

LNOCIAQAgent  *agent;
text        *appname;
text        *queue;
LNOCIError    *errhp;
{

  OCIAttrSet(agent, OCI_DTYPE_AQAGENT, 
     appname ? (dvoid *)appname : (dvoid *)"", 
     appname ? strlen((const char *)appname) : 0,
        OCI_ATTR_AGENT_NAME, errhp);

  OCIAttrSet(agent, OCI_DTYPE_AQAGENT, 
     queue ? (dvoid *)queue : (dvoid *)"", 
     queue ? strlen((const char *)queue) : 0,
        OCI_ATTR_AGENT_ADDRESS, errhp);

  printf("Set agent name to %s\n", appname ? (char *)appname : "NULL");
  printf("Set agent address to %s\n", queue ? (char *)queue : "NULL");
}

/* get agent from descriptor */
void GetAgent(agent, errhp)
LNOCIAQAgent *agent;
LNOCIError   *errhp;
{
text      *appname;
text      *queue;
ub4       appsz;
ub4       queuesz;

  if (!agent )
  {
    printf("agent was NULL \n");
    return;
  }
  checkerr(errhp, OCIAttrGet(agent, OCI_DTYPE_AQAGENT, 
     (dvoid *)&appname, &appsz, OCI_ATTR_AGENT_NAME, errhp));
  checkerr(errhp, OCIAttrGet(agent, OCI_DTYPE_AQAGENT, 
     (dvoid *)&queue, &queuesz, OCI_ATTR_AGENT_ADDRESS, errhp));
  if (!appsz)
     printf("agent name: NULL\n");
  else printf("agent name: %.*s\n", appsz, (char *)appname);
  if (!queuesz)
     printf("agent address: NULL\n");
  else printf("agent address: %.*s\n", queuesz, (char *)queue);
}

int main()
{
  OCIEnv *envhp;
  OCIServer *srvhp;
  OCIError *errhp;
  OCISvcCtx *svchp;
  OCISession *usrhp;
  OCIAQAgent *agent_list[3];
  OCIAQAgent *agent = (OCIAQAgent *)0;
  /* added next 2 121598 */
  int i;

 /* Standard OCI Initialization */

  OCIInitialize((ub4) OCI_OBJECT, (dvoid *)0,  (dvoid * (*)()) 0,
     (dvoid * (*)()) 0,  (void (*)()) 0 );
 
  OCIHandleAlloc( (dvoid *) NULL, (dvoid **) &envhp, 
             (ub4) OCI_HTYPE_ENV, 0, (dvoid **) 0);
  
  OCIEnvInit( &envhp, (ub4) OCI_DEFAULT, 0, (dvoid **) 0);
  
  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, (ub4) OCI_HTYPE_ERROR,
     0, (dvoid **) 0);

  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, (ub4) OCI_HTYPE_SERVER,
     0, (dvoid **) 0);
  
  OCIServerAttach( srvhp, errhp, (text *) 0, (sb4) 0, (ub4) OCI_DEFAULT);
  
  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, (ub4) OCI_HTYPE_SVCCTX,
     0, (dvoid **) 0);
  
  /* set attribute server context in the service context */
  OCIAttrSet( (dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4) 0,
     (ub4) OCI_ATTR_SERVER, (OCIError *) errhp);
  
  /* allocate a user context handle */
  OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4) OCI_HTYPE_SESSION,
      (size_t) 0, (dvoid **) 0);
  
  /* allocate a user context handle */
  OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4) OCI_HTYPE_SESSION,
     (size_t) 0, (dvoid **) 0);
  
  OCIAttrSet((dvoid *)usrhp, (ub4)OCI_HTYPE_SESSION,
     (dvoid *)"scott", (ub4)strlen("scott"), OCI_ATTR_USERNAME, errhp);
   
  OCIAttrSet((dvoid *) usrhp, (ub4) OCI_HTYPE_SESSION,
      (dvoid *) "tiger", (ub4) strlen("tiger"),
      (ub4) OCI_ATTR_PASSWORD, errhp);   
  
  OCISessionBegin (svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT);
  
  OCIAttrSet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX,
     (dvoid *)usrhp, (ub4)0, OCI_ATTR_SESSION, errhp);

  /* AQ LISTEN Initialization - allocate agent handles */
  for (i = 0; i < 3; i++)
  {
     agent_list[i] = (OCIAQAgent *)0;
     OCIDescriptorAlloc(envhp, (dvoid **)&agent_list[i], 
         OCI_DTYPE_AQAGENT, 0, (dvoid **)0);
  }

  /* 
   *   SCQ1, SCQ2, SCQ3 are single-consumer queues in SCOTT's schema
   */
 
  SetAgent(agent_list[0], (text *)0, "SCOTT.SCQ1", errhp);
  SetAgent(agent_list[1], (text *)0, "SCOTT.SCQ2", errhp);
  SetAgent(agent_list[2], (text *)0, "SCOTT.SCQ3", errhp);
 
  checkerr(errhp,OCIAQListen(svchp, errhp, agent_list, 3, 0, &agent, 0));

  printf("MESSAGE for :- \n");             
  GetAgent(agent, errhp);
  printf("\n");

}

Listening for Single-Consumer Queues with Timeout of 120 Seconds

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>

static void checkerr(errhp, status)
LNOCIError *errhp;
sword status;
{
    text errbuf[512];
    ub4 buflen;
    sb4 errcode;

    switch (status)
    {
   case OCI_SUCCESS:
       break;
   case OCI_SUCCESS_WITH_INFO:
       printf("Error - OCI_SUCCESS_WITH_INFO\n");
       break;
   case OCI_NEED_DATA:
       printf("Error - OCI_NEED_DATA\n");
       break;
   case OCI_NO_DATA:
       printf("Error - OCI_NO_DATA\n");
       break;
   case OCI_ERROR:
       OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode,
       errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
       printf("Error - %s\n", errbuf);
       break;
   case OCI_INVALID_HANDLE:
       printf("Error - OCI_INVALID_HANDLE\n");
       break;
   case OCI_STILL_EXECUTING:
       printf("Error - OCI_STILL_EXECUTE\n");
       break;
   case OCI_CONTINUE:
       printf("Error - OCI_CONTINUE\n");
       break;
   default:
   break;
    }
}

/* set agent into descriptor */
/* void SetAgent(agent, appname, queue) */
void SetAgent(agent, appname, queue,errhp)

LNOCIAQAgent  *agent;
text        *appname;
text        *queue;
LNOCIError    *errhp;
{

  OCIAttrSet(agent, OCI_DTYPE_AQAGENT, 
     appname ? (dvoid *)appname : (dvoid *)"", 
     appname ? strlen((const char *)appname) : 0,
        OCI_ATTR_AGENT_NAME, errhp);

  OCIAttrSet(agent, OCI_DTYPE_AQAGENT, 
     queue ? (dvoid *)queue : (dvoid *)"", 
     queue ? strlen((const char *)queue) : 0,
        OCI_ATTR_AGENT_ADDRESS, errhp);

  printf("Set agent name to %s\n", appname ? (char *)appname : "NULL");
  printf("Set agent address to %s\n", queue ? (char *)queue : "NULL");
}

/* get agent from descriptor */
void GetAgent(agent, errhp)
LNOCIAQAgent *agent;
LNOCIError   *errhp;
{
text      *appname;
text      *queue;
ub4       appsz;
ub4       queuesz;

  if (!agent )
  {
    printf("agent was NULL \n");
    return;
  }
  checkerr(errhp, OCIAttrGet(agent, OCI_DTYPE_AQAGENT, 
     (dvoid *)&appname, &appsz, OCI_ATTR_AGENT_NAME, errhp));
  checkerr(errhp, OCIAttrGet(agent, OCI_DTYPE_AQAGENT, 
     (dvoid *)&queue, &queuesz, OCI_ATTR_AGENT_ADDRESS, errhp));
  if (!appsz)
     printf("agent name: NULL\n");
  else printf("agent name: %.*s\n", appsz, (char *)appname);
  if (!queuesz)
     printf("agent address: NULL\n");
  else printf("agent address: %.*s\n", queuesz, (char *)queue);
}

int main()
{
  OCIEnv *envhp;
  OCIServer *srvhp;
  OCIError *errhp;
  OCISvcCtx *svchp;
  OCISession *usrhp;
  OCIAQAgent *agent_list[3];
  OCIAQAgent *agent = (OCIAQAgent *)0;
  /* added next 2 121598 */
  int i;

 /* Standard OCI Initialization */

  OCIInitialize((ub4) OCI_OBJECT, (dvoid *)0,  (dvoid * (*)()) 0,
     (dvoid * (*)()) 0,  (void (*)()) 0 );
 
  OCIHandleAlloc( (dvoid *) NULL, (dvoid **) &envhp, 
             (ub4) OCI_HTYPE_ENV, 0, (dvoid **) 0);
  
  OCIEnvInit( &envhp, (ub4) OCI_DEFAULT, 0, (dvoid **) 0);
  
  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, (ub4) OCI_HTYPE_ERROR,
     0, (dvoid **) 0);

  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, (ub4) OCI_HTYPE_SERVER,
     0, (dvoid **) 0);
  
  OCIServerAttach( srvhp, errhp, (text *) 0, (sb4) 0, (ub4) OCI_DEFAULT);
  
  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, (ub4) OCI_HTYPE_SVCCTX,
     0, (dvoid **) 0);
  
  /* set attribute server context in the service context */
  OCIAttrSet( (dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4) 0,
     (ub4) OCI_ATTR_SERVER, (OCIError *) errhp);
  
  /* allocate a user context handle */
  OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4) OCI_HTYPE_SESSION,
      (size_t) 0, (dvoid **) 0);
  
  /* allocate a user context handle */
  OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4) OCI_HTYPE_SESSION,
     (size_t) 0, (dvoid **) 0);
  
  OCIAttrSet((dvoid *)usrhp, (ub4)OCI_HTYPE_SESSION,
     (dvoid *)"scott", (ub4)strlen("scott"), OCI_ATTR_USERNAME, errhp);
   
  OCIAttrSet((dvoid *) usrhp, (ub4) OCI_HTYPE_SESSION,
      (dvoid *) "tiger", (ub4) strlen("tiger"),
      (ub4) OCI_ATTR_PASSWORD, errhp);   
  
  OCISessionBegin (svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT);
  
  OCIAttrSet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX,
     (dvoid *)usrhp, (ub4)0, OCI_ATTR_SESSION, errhp);

  /* AQ LISTEN Initialization - allocate agent handles */
  for (i = 0; i < 3; i++)
  {
     agent_list[i] = (OCIAQAgent *)0;
     OCIDescriptorAlloc(envhp, (dvoid **)&agent_list[i], 
         OCI_DTYPE_AQAGENT, 0, (dvoid **)0);
  }

  /* 
   *   SCQ1, SCQ2, SCQ3 are single-consumer queues in SCOTT's schema
   */
 
  SetAgent(agent_list[0], (text *)0, "SCOTT.SCQ1", errhp);
  SetAgent(agent_list[1], (text *)0, "SCOTT.SCQ2", errhp);
  SetAgent(agent_list[2], (text *)0, "SCOTT.SCQ3", errhp);
 
  checkerr(errhp,OCIAQListen(svchp, errhp, agent_list, 3, 120, &agent, 0));

  printf("MESSAGE for :- \n");             
  GetAgent(agent, errhp);
  printf("\n");

}

Listening to One or More Multiconsumer Queues

Figure 11-7 Listening to One or More Multiconsumer Queues

Text description of adque091.gif follows
Text description of the illustration adque091.gif


See Also:

Usage Notes

See the usage notes in "Listening to One or More Single-Consumer Queues".

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

PL/SQL (DBMS_AQ Package): Listen to Queues
/* The listen call allows you to monitor a list of queues for messages for 
 specific agents. You need to have dequeue privileges for all the queues 
 you wish to monitor. */

Listen to Multiconsumer Queue (Timeout of Zero).

DECLARE
   Agent_w_msg      aq$_agent;
   My_agent_list    dbms_aq.agent_list_t;

BEGIN
   /* NOTE:  MCQ1, MCQ2, MCQ3 are multiconsumer queues  in SCOTT's schema
   *        SCQ1, SCQ2, SCQ3 are single-consumer queues in SCOTT's schema
   */
    Qlist(1):= aq$_agent('agent1', 'MCQ1',  NULL);
    Qlist(2):= aq$_agent('agent2', 'scott.MCQ2', NULL);
    Qlist(3):= aq$_agent('agent3', 'scott.MCQ3', NULL);

 /* Listen with a time-out of zero: */
   DBMS_AQ.LISTEN(
      agent_list   =>    My_agent_list, 
      wait         =>    0, 
      agent        =>    agent_w_msg);
   DBMS_OUTPUT.PUT_LINE('Message in Queue :- ' ||  agent_w_msg.address);
   DBMS_OUTPUT.PUT_LINE('');
END;
   /

Listen to Mixture of Multiconsumer Queues (Timeout 100 Seconds).

DECLARE
   Agent_w_msg      aq$_agent;
   My_agent_list    dbms_aq.agent_list_t;

BEGIN
   /* NOTE:  MCQ1, MCQ2, MCQ3 are multiconsumer queues  in SCOTT's schema
   *        SCQ1, SCQ2, SCQ3 are single-consumer queues in SCOTT's schema
   */
   Qlist(1):= aq$_agent('agent1', 'MCQ1',  NULL);
   Qlist(2):= aq$_agent(NULL, 'scott.SQ1', NULL);
   Qlist(3):= aq$_agent('agent3', 'scott.MCQ3', NULL);
  /* Listen with a time-out of 100 seconds */
   DBMS_AQ.LISTEN(
      Agent_list   =>   My_agent_list, 
      Wait         =>   100, 
      Agent        =>    agent_w_msg);
      DBMS_OUTPUT.PUT_LINE('Message in Queue :- ' ||  agent_w_msg.address 
                           || 'for agent' || agent_w_msg.name);
      DBMS_OUTPUT.PUT_LINE('');
   END;
   /
C (OCI): Listen to Multiconsumer Queues

Listening to Multiconsumer Queues with a Zero Timeout, a Timeout of 120 Seconds, and a Timeout of 100 Seconds

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>

static void checkerr(errhp, status)
LNOCIError *errhp;
sword status;
{
    text errbuf[512];
    ub4 buflen;
    sb4 errcode;

    switch (status)
    {
   case OCI_SUCCESS:
       break;
   case OCI_SUCCESS_WITH_INFO:
       printf("Error - OCI_SUCCESS_WITH_INFO\n");
       break;
   case OCI_NEED_DATA:
       printf("Error - OCI_NEED_DATA\n");
       break;
   case OCI_NO_DATA:
       printf("Error - OCI_NO_DATA\n");
       break;
   case OCI_ERROR:
       OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode,
       errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
       printf("Error - %s\n", errbuf);
       break;
   case OCI_INVALID_HANDLE:
       printf("Error - OCI_INVALID_HANDLE\n");
       break;
   case OCI_STILL_EXECUTING:
       printf("Error - OCI_STILL_EXECUTE\n");
       break;
   case OCI_CONTINUE:
       printf("Error - OCI_CONTINUE\n");
       break;
   default:
   break;
    }
}

void SetAgent(OCIAQAgent *agent, 
         text       *appname, 
         text       *queue,
         OCIError   *errhp,
         OCIEnv     *envhp);

void GetAgent(OCIAQAgent *agent, 
         OCIError   *errhp);

/*----------------------------------------------------------------*/
/* OCI Listen examples for multiconsumers                        */
/*                                                                */
void SetAgent(agent, appname, queue, errhp)
LNOCIAQAgent    *agent;
text          *appname;
text          *queue;
LNOCIError      *errhp;
{
  OCIAttrSet(agent, 
        OCI_DTYPE_AQAGENT, 
        appname ? (dvoid *)appname : (dvoid *)"", 
        appname ? strlen((const char *)appname) : 0,
             OCI_ATTR_AGENT_NAME, 
        errhp);

  OCIAttrSet(agent, 
        OCI_DTYPE_AQAGENT, 
        queue ? (dvoid *)queue : (dvoid *)"", 
        queue ? strlen((const char *)queue) : 0,
             OCI_ATTR_AGENT_ADDRESS, 
        errhp);

  printf("Set agent name to %s\n", appname ? (char *)appname : "NULL");
  printf("Set agent address to %s\n", queue ? (char *)queue : "NULL");
}

/* get agent from descriptor */
void GetAgent(agent, errhp)
LNOCIAQAgent *agent;
LNOCIError   *errhp;
{
   text      *appname;
   text      *queue;
   ub4       appsz;
   ub4       queuesz;

   if (!agent )
  {
     printf("agent was NULL \n");
     return;
  }
  checkerr(errhp, OCIAttrGet(agent, OCI_DTYPE_AQAGENT, 
     (dvoid *)&appname, &appsz, OCI_ATTR_AGENT_NAME, errhp));
  checkerr(errhp, OCIAttrGet(agent, OCI_DTYPE_AQAGENT, 
     (dvoid *)&queue, &queuesz, OCI_ATTR_AGENT_ADDRESS, errhp));
  if (!appsz)
     printf("agent name: NULL\n");
  else printf("agent name: %.*s\n", appsz, (char *)appname);
  if (!queuesz)
     printf("agent address: NULL\n");
  else printf("agent address: %.*s\n", queuesz, (char *)queue);
}

/* main from AQ Listen to multiconsumer Queues */

/*  int main() */
int main(char *argv, int argc)
{
    OCIEnv     *envhp;
    OCIServer  *srvhp;
    OCIError   *errhp;
    OCISvcCtx  *svchp;
    OCISession *usrhp;
    OCIAQAgent *agent_list[3];
    OCIAQAgent *agent;
    int         i;

 /* Standard OCI Initialization */

  OCIInitialize((ub4) OCI_OBJECT, 
      (dvoid *)0,  
      (dvoid * (*)()) 0,
      (dvoid * (*)()) 0,  
      (void (*)()) 0 );
  
  OCIHandleAlloc( (dvoid *) NULL, (dvoid **) &envhp, (ub4) OCI_HTYPE_ENV,
     0, (dvoid **) 0);
  
  OCIEnvInit( &envhp, (ub4) OCI_DEFAULT, 0, (dvoid **)0);
  
  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, (ub4) OCI_HTYPE_ERROR,
     0, (dvoid **) 0);

  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, (ub4) OCI_HTYPE_SERVER,
     0, (dvoid **) 0);
  
  OCIServerAttach( srvhp, errhp, (text *) 0, (sb4) 0, (ub4) OCI_DEFAULT);
  
  OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, (ub4) OCI_HTYPE_SVCCTX,
     0, (dvoid **) 0);
  
  /* set attribute server context in the service context */
  OCIAttrSet( (dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4) 0,
     (ub4) OCI_ATTR_SERVER, (OCIError *) errhp);
  
   /* allocate a user context handle */
  OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4) OCI_HTYPE_SESSION,
     (size_t) 0, (dvoid **) 0);
  
   /* allocate a user context handle */
  OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4) OCI_HTYPE_SESSION,
     (size_t) 0, (dvoid **) 0);
  
  
  OCIAttrSet((dvoid *)usrhp, (ub4)OCI_HTYPE_SESSION,
     (dvoid *)"scott", (ub4)strlen("scott"), OCI_ATTR_USERNAME, errhp);
   

   OCIAttrSet((dvoid *) usrhp, (ub4) OCI_HTYPE_SESSION,
      (dvoid *) "tiger", (ub4) strlen("tiger"),
      (ub4) OCI_ATTR_PASSWORD, errhp);   
  
  OCISessionBegin (svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT);
  
  OCIAttrSet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX,
     (dvoid *)usrhp, (ub4)0, OCI_ATTR_SESSION, errhp);

  /* AQ LISTEN Initialization - allocate agent handles */
  for (i = 0; i < 3; i++)
  {
     OCIDescriptorAlloc(envhp, (dvoid **)&agent_list[i], 
         OCI_DTYPE_AQAGENT, 0, (dvoid **)0);
  }

  /* 
   *  MCQ1, MCQ2, MCQ3 are multiconsumer queues in SCOTT's schema 
   */
  /* Listening to Multiconsumer Queues with Zero Timeout */

  SetAgent(agent_list[0], "app1", "MCQ1", errhp);
  SetAgent(agent_list[1], "app2", "MCQ2", errhp);
  SetAgent(agent_list[2], "app3", "MCQ3", errhp);
 
  checkerr(errhp, OCIAQListen(svchp, errhp, agent_list, 3, 0, &agent, 0));

  printf("MESSAGE for :- \n");             
  GetAgent(agent, errhp);
  printf("\n");


  /* Listening to Multiconsumer Queues with Timeout of 120 Seconds */

  SetAgent(agent_list[0], "app1", "SCOTT.MCQ1", errhp);
  SetAgent(agent_list[1], "app2", "SCOTT.MCQ2", errhp);
  SetAgent(agent_list[2], "app3", "SCOTT.MCQ3", errhp);
 
  checkerr(errhp, OCIAQListen(svchp, errhp, agent_list, 3, 120, &agent, 0));

  printf("MESSAGE for :- \n");             
  GetAgent(agent, errhp);
  printf("\n");


  /* Listening to a Mixture of Single and Multiconsumer Queues 
   * with a Timeout of 100 Seconds
   */

  SetAgent(agent_list[0], "app1", "SCOTT.MCQ1", errhp);
  SetAgent(agent_list[1], "app2", "SCOTT.MCQ2", errhp);
  SetAgent(agent_list[2], (text *)0, "SCOTT.SCQ3", errhp);
 
  checkerr(errhp, OCIAQListen(svchp, errhp, agent_list, 3, 100, &agent, 0));

  printf("MESSAGE for :- \n");             
  GetAgent(agent, errhp);
  printf("\n");

}

Dequeuing a Message

Figure 11-8 Dequeuing a Message

Text description of adque093.gif follows
Text description of the illustration adque093.gif


See Also:

Purpose

Dequeues a message from the specified queue.

Usage Notes

Search criteria and dequeue order for messages:

Navigating through a queue

The default NAVIGATION parameter during dequeue is NEXT MESSAGE. This means that subsequent dequeues will retrieve the messages from the queue based on the snapshot obtained in the first dequeue. In particular, a message that is enqueued after the first dequeue command will be processed only after processing all the remaining messages in the queue. This is usually sufficient when all the messages have already been enqueued into the queue, or when the queue does not have a priority-based ordering. However, applications must use the FIRST MESSAGE navigation option when the first message in the queue needs to be processed by every dequeue command. This usually becomes necessary when a higher priority message arrives in the queue while messages already-enqueued are being processed.


Note:

It may also be more efficient to use the FIRST MESSAGE navigation option when there are messages being concurrently enqueued. If the FIRST MESSAGE option is not specified, AQ will have to continually generate the snapshot as of the first dequeue command, leading to poor performance. If the FIRST MESSAGE option is specified, AQ will use a new snapshot for every dequeue command.


Dequeue by Message Grouping

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

Dequeuing a Message from a Single-Consumer Queue [SpecifyOptions]

Figure 11-9 Dequeuing a Message from a Single-Consumer Queue

Text description of adque094.gif follows
Text description of the illustration adque094.gif


See Also:

Purpose

To specify the options available for the dequeue operation.

Usage Notes

Typically, you expect the consumer of messages to access messages using the dequeue interface. You can view processed messages or messages still to be processed by browsing by message id or by using SELECTs.

The transformation, if specified, is applied before returning the message to the caller. The transformation should be defined to map the queue ADT type to the return type desired by the caller.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

PL/SQL (DBMS_AQ Package): Dequeue of Object Type Messages
/* Dequeue from msg_queue: */
DECLARE
dequeue_options     dbms_aq.dequeue_options_t;
message_properties  dbms_aq.message_properties_t;
message_handle      RAW(16);
message             aq.message_typ;

BEGIN
   DBMS_AQ.DEQUEUE(
      queue_name          =>     'msg_queue',
      dequeue_options      =>    dequeue_options,
      message_properties  =>     message_properties,
      payload             =>     message,
      msgid               =>     message_handle);

   DBMS_OUTPUT.PUT_LINE ('Message: ' || message.subject ||
                                      ' ... ' || message.text );
   COMMIT;
END;
Java (JDBC): Dequeue a message from a single-consumer queue (specify options)
/* Dequeue a message with correlation id = 'RUSH' */
public static void example(AQSession aq_sess) throws AQException, SQLException
{
     AQQueue                  queue;
     AQMessage                message;
     AQRawPayload             raw_payload;
     AQDequeueOption          deq_option;
     byte[]                   b_array;
     Connection               db_conn;

     db_conn = ((AQOracleSession)aq_sess).getDBConnection();

     queue = aq_sess.getQueue ("aq", "msg_queue");

     /* Create a AQDequeueOption object with default options: */
     deq_option = new AQDequeueOption();

     deq_option.setCorrelation("RUSH");

     /* Dequeue a message */
     message = queue.dequeue(deq_option);

     System.out.println("Successful dequeue"); 
    
     /* Retrieve raw data from the message: */
     raw_payload = message.getRawPayload();
 
     b_array = raw_payload.getBytes();

     db_conn.commit();
}
Visual Basic (OO4O): Dequeue a message

Dequeuing messages of RAW type

 'Dequeue the first message available  
Q.Dequeue() 
Set Msg = Q.QMsg 

'Display the message content 
MsgBox Msg.Value 

'Dequeue the first message available without removing it 
' from the queue 
Q.DequeueMode = ORAAQ_DEQ_BROWSE 

'Dequeue the first message with the correlation identifier 
' equal to "RELATIVE_MSG_ID" 
Q.Navigation = ORAAQ_DQ_FIRST_MSG 
Q.correlate = "RELATIVE_MESSAGE_ID" 
Q.Dequeue 

'Dequeue the next message with the correlation identifier 

' of "RELATIVE_MSG_ID" 
Q.Navigation = ORAAQ_DQ_NEXT_MSG 
Q.Dequeue() 

'Dequeue the first high priority message 
Msg.Priority = ORAQMSG_HIGH_PRIORITY 
Q.Dequeue() 

'Dequeue the message enqueued with message id of Msgid_1 
Q.DequeueMsgid = Msgid_1 
Q.Dequeue() 

'Dequeue the message meant for "ANDY" 
Q.consumer = "ANDY" 
Q.Dequeue() 

'Return immediately if there is no message on the queue  
Q.wait = ORAAQ_DQ_NOWAIT 
Q.Dequeue()

Dequeuing messages of Oracle object type

Set OraObj = DB.CreateOraObject("MESSAGE_TYPE") 
Set QMsg = Q.AQMsg(1, "MESSAGE_TYPE") 

'Dequeue the first message available without removing it 
Q.Dequeue() 
OraObj = QMsg.Value 

'Display the subject and data 
MsgBox OraObj!subject & OraObj!Data

Dequeuing a Message from a Multiconsumer Queue [Specify Options]

Figure 11-10 Dequeuing a Message from a Multiconsumer Queue

Text description of adque096.gif follows
Text description of the illustration adque096.gif


See Also:

Purpose

To specify the options available for the dequeue operation.

Usage Notes

Not applicable.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

Examples in the following programmatic environments are provided:

Java (JDBC): Dequeue a message from a multiconsumer queue (specify options)

/* Dequeue a message for subscriber1 in browse mode*/
public static void example(AQSession aq_sess) throws AQException, SQLException
{
     AQQueue                  queue;
     AQMessage                message;
     AQRawPayload             raw_payload;
     AQDequeueOption          deq_option;
     byte[]                   b_array;
     Connection               db_conn;

     db_conn = ((AQOracleSession)aq_sess).getDBConnection();

     queue = aq_sess.getQueue ("aq", "priority_msg_queue");

     /* Create a AQDequeueOption object with default options: */
     deq_option = new AQDequeueOption();

     /* Set dequeue mode to BROWSE */
     deq_option.setDequeueMode(AQDequeueOption.DEQUEUE_BROWSE);

     /* Dequeue messages for subscriber1 */
     deq_option.setConsumerName("subscriber1");

     /* Dequeue a message: */
     message = queue.dequeue(deq_option);

     System.out.println("Successful dequeue"); 
    
     /* Retrieve raw data from the message: */
     raw_payload = message.getRawPayload();
 
     b_array = raw_payload.getBytes();

     db_conn.commit();
}

Registering for Notification

Figure 11-11 Registering for Notification

Text description of adque412.gif follows
Text description of the illustration adque412.gif


See Also:

Purpose

To register a callback for message notification.

Usage Notes

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Examples in the following programmatic environments are provided:

Registering for Notification [Specifying Subscription Name--Single-Consumer Queue]

Figure 11-12 Specifying Subscription Name--Single-Consumer Queue

Text description of adque098.gif follows
Text description of the illustration adque098.gif


See Also:

Registering for Notification [Specifying Subscription Name--Multiconsumer Queue]

Figure 11-13 Specifying Subscription Name - Multiconsumer Queue

Text description of adque099.gif follows
Text description of the illustration adque099.gif


See Also:

Usage Notes

Not applicable.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment.

C (OCI): Register for Notifications For Single-Consumer and Multiconsumer Queries
/* OCIRegister can be used by the client to register to receive notifications 
   when messages are enqueued into non-persistent and normal queues. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>


static OCIEnv     *envhp;
static OCIServer  *srvhp;
static OCIError   *errhp;
static OCISvcCtx  *svchp;


/* The callback that gets invoked on notification */
ub4 notifyCB(ctx, subscrhp, pay, payl, desc, mode)
dvoid *ctx;
LNOCISubscription *subscrhp;      /* subscription handle */
dvoid           *pay;           /* payload  */
ub4              payl;          /* payload length */
dvoid           *desc;        /* the AQ notification descriptor */
ub4              mode;
{
 text                *subname;
 ub4                  size;
 ub4                 *number = (ub4 *)ctx;
 text                *queue;
 text                *consumer;
 OCIRaw              *msgid;
 OCIAQMsgProperties  *msgprop;

  (*number)++;

 /* Get the subscription name */
  OCIAttrGet((dvoid *)subscrhp, OCI_HTYPE_SUBSCRIPTION,
                             (dvoid *)&subname, &size,
                             OCI_ATTR_SUBSCR_NAME, errhp);
 printf("got notification number %d for %.*s  %d  \n", 
         *number, size, subname, payl);

 /* Get the queue name from the AQ notify descriptor */
 OCIAttrGet(desc, OCI_DTYPE_AQNFY_DESCRIPTOR, (dvoid *)&queue, &size, 
             OCI_ATTR_QUEUE_NAME, errhp);
 
 /* Get the consumer name for which this notification was received */
 OCIAttrGet(desc, OCI_DTYPE_AQNFY_DESCRIPTOR, (dvoid *)&consumer, &size, 
       OCI_ATTR_CONSUMER_NAME, errhp);

 /* Get the message id of the message for which we were notified */
 OCIAttrGet(desc, OCI_DTYPE_AQNFY_DESCRIPTOR, (dvoid *)&msgid, &size, 
       OCI_ATTR_NFY_MSGID, errhp);

 /* Get the message properties of the message for which we were notified */
 OCIAttrGet(desc, OCI_DTYPE_AQNFY_DESCRIPTOR, (dvoid *)&msgprop, &size, 
       OCI_ATTR_MSG_PROP, errhp);

}


int main(argc, argv)
int argc;
char *argv[];
{
  OCISession *authp = (OCISession *) 0;

 /* The subscription handles */
  OCISubscription *subscrhp[5];

 /* Registrations are for AQ namespace */
  ub4 namespace = OCI_SUBSCR_NAMESPACE_AQ;   

 /* The context fot the callback */
  ub4 ctx[5] = {0,0,0,0,0};

  printf("Initializing OCI Process\n");

 /* The OCI Process Environment must be initialized  with OCI_EVENTS */
 /* OCI_OBJECT flag is set to enable us dequeue */
  (void) OCIInitialize((ub4) OCI_EVENTS|OCI_OBJECT, (dvoid *)0,
                       (dvoid * (*)(dvoid *, size_t)) 0,
                       (dvoid * (*)(dvoid *, dvoid *, size_t))0,
                       (void (*)(dvoid *, dvoid *)) 0 );

  printf("Initialization successful\n");

 /* The standard OCI setup */
  printf("Initializing OCI Env\n");
  (void) OCIEnvInit((OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0, 
                (dvoid **) 0 );

  (void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR, 
                   (size_t) 0, (dvoid **) 0);

 /* Server contexts */
  (void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,
                   (size_t) 0, (dvoid **) 0);

  (void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,
                   (size_t) 0, (dvoid **) 0);


  printf("connecting to server\n");
  (void) OCIServerAttach( srvhp, errhp, (text *)"", strlen(""), 0);
  printf("connect successful\n");

 /* Set attribute server context in the service context */
  (void) OCIAttrSet( (dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp, 
          (ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp);

  (void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&authp,
             (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);
 
  (void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
                 (dvoid *) "scott", (ub4) strlen("scott"),
                 (ub4) OCI_ATTR_USERNAME, errhp);
 
  (void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
                 (dvoid *) "tiger", (ub4) strlen("tiger"),
                 (ub4) OCI_ATTR_PASSWORD, errhp);

  checkerr(errhp, OCISessionBegin ( svchp,  errhp, authp, OCI_CRED_RDBMS, 
           (ub4) OCI_DEFAULT));

  (void) OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX,
                   (dvoid *) authp, (ub4) 0,
                   (ub4) OCI_ATTR_SESSION, errhp);

 /* Setting the subscription handle for notification on
 a NORMAL single-consumer queue */
  printf("allocating subscription handle\n");
  subscrhp[0] = (OCISubscription *)0;
  (void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&subscrhp[0], 
         (ub4) OCI_HTYPE_SUBSCRIPTION,
         (size_t) 0, (dvoid **) 0);
 
  printf("setting subscription name\n");
  (void) OCIAttrSet((dvoid *) subscrhp[0], (ub4) OCI_HTYPE_SUBSCRIPTION,
                (dvoid *) "SCOTT.SCQ1", (ub4) strlen("SCOTT.SCQ1"),
                (ub4) OCI_ATTR_SUBSCR_NAME, errhp);
 
  printf("setting subscription callback\n");
  (void) OCIAttrSet((dvoid *) subscrhp[0], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) notifyCB, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_CALLBACK, errhp);

 printf("setting subscription context \n");
 (void) OCIAttrSet((dvoid *) subscrhp[0], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *)&ctx[0], (ub4)sizeof(ctx[0]),
                 (ub4) OCI_ATTR_SUBSCR_CTX, errhp);

  printf("setting subscription namespace\n");
  (void) OCIAttrSet((dvoid *) subscrhp[0], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) &namespace, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_NAMESPACE, errhp);

 /* Setting the subscription handle for notification on a NORMAL multiconsumer 
 consumer queue */
  subscrhp[1] = (OCISubscription *)0;
  (void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&subscrhp[1], 
         (ub4) OCI_HTYPE_SUBSCRIPTION,
         (size_t) 0, (dvoid **) 0);

  (void) OCIAttrSet((dvoid *) subscrhp[1], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) "SCOTT.MCQ1:APP1", 
                 (ub4) strlen("SCOTT.MCQ1:APP1"),
                 (ub4) OCI_ATTR_SUBSCR_NAME, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[1], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) notifyCB, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_CALLBACK, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[1], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *)&ctx[1], (ub4)sizeof(ctx[1]),
                 (ub4) OCI_ATTR_SUBSCR_CTX, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[1], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) &namespace, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_NAMESPACE, errhp);


 /* Setting the subscription handle for notification on a non-persistent   
 single-consumer queue */
  subscrhp[2] = (OCISubscription *)0;
  (void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&subscrhp[2], 
         (ub4) OCI_HTYPE_SUBSCRIPTION,
         (size_t) 0, (dvoid **) 0);

  (void) OCIAttrSet((dvoid *) subscrhp[2], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) "SCOTT.NP_SCQ1", 
                 (ub4) strlen("SCOTT.NP_SCQ1"),
                 (ub4) OCI_ATTR_SUBSCR_NAME, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[2], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) notifyCB, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_CALLBACK, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[2], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *)&ctx[2], (ub4)sizeof(ctx[2]),
                 (ub4) OCI_ATTR_SUBSCR_CTX, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[2], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) &namespace, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_NAMESPACE, errhp);


 /* Setting the subscription handle for notification on
 a non-persistent multi consumer queue */
 /* Waiting on user specified recipient */
  subscrhp[3] = (OCISubscription *)0;
  (void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&subscrhp[3], 
         (ub4) OCI_HTYPE_SUBSCRIPTION,
         (size_t) 0, (dvoid **) 0);

  (void) OCIAttrSet((dvoid *) subscrhp[3], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) "SCOTT.NP_MCQ1", 
                 (ub4) strlen("SCOTT.NP_MCQ1"),
                 (ub4) OCI_ATTR_SUBSCR_NAME, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[3], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) notifyCB, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_CALLBACK, errhp);

 (void) OCIAttrSet((dvoid *) subscrhp[3], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *)&ctx[3], (ub4)sizeof(ctx[3]),
                 (ub4) OCI_ATTR_SUBSCR_CTX, errhp);

  (void) OCIAttrSet((dvoid *) subscrhp[3], (ub4) OCI_HTYPE_SUBSCRIPTION,
                 (dvoid *) &namespace, (ub4) 0,
                 (ub4) OCI_ATTR_SUBSCR_NAMESPACE, errhp);


  printf("Registering for all the subscriptiosn \n");
  checkerr(errhp, OCISubscriptionRegister(svchp, subscrhp, 4, errhp, 
                 OCI_DEFAULT));

  printf("Waiting for notifcations \n");
  
  /* wait for minutes for notifications */
  sleep(300);

  printf("Exiting\n");
}

Posting for Subscriber Notification

Figure 11-14 Posting for Subscriber Notification

Text description of adque413.gif follows
Text description of the illustration adque413.gif


See Also:

Table 11-1 for a list of operational interface basic operations

Purpose

To post to a list of anonymous subscriptions so clients registered for the subscription get notifications.

Usage Notes

Several subscriptions can be posted to at one time. Posting to a subscription involves identifying the subscription name and the payload, if desired. It is possible for no payload to be associated with this call. This call provides a best-effort guarantee. A notification goes to registered clients at most once.

This call is primarily used for lightweight notification and is useful in the case of several system events. If an application needs more rigid guarantees, it can use AQ functionality by enqueuing to a queue.

When using OCI, the user must specify a subscription handle at registration time with the namespace attribute set to OCI_SUBSCR_NAMESPACE_ANONYMOUS.

When using PL/SQL, the namespace attribute in aq$_post_info must be set to DBMS_AQ.NAMESPACE_ANONYMOUS.

Related functions: LNOCIAQListen(), OCISvcCtxToLda(), LNOCISubscriptionEnable(), OCISubscriptionRegister(), LNOCISubscriptionUnRegister(), dbms_aq.register, dbms_aq.unregister.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment.

PL/SQL (DBMS_AQ Package): Post of Object-Type Messages
-- Register for notification
DECLARE
  reginfo             sys.aq$_reg_info;
  reginfolist         sys.aq$_reg_info_list;

BEGIN
  -- Register for anonymous subscription PUBSUB1.ANONSTR, consumer_name ADMIN
  -- The PL/SQL callback pubsub1.mycallbk will be invoked 
  -- when a notification is received
  reginfo := sys.aq$_reg_info('PUBSUB1.ANONSTR:ADMIN',
                  DBMS_AQ.NAMESPACE_ANONYMOUS,
      'plsql://PUBSUB1.mycallbk', HEXTORAW('FF'));

  reginfolist := sys.aq$_reg_info_list(reginfo);

  sys.dbms_aq.register(reginfolist, 1);

  commit;
END;
/

-- Post to an anonymous subscription
DECLARE

  postinfo            sys.aq$_post_info;
  postinfolist        sys.aq$_post_info_list;

BEGIN

  -- Post to the anonymous subscription PUBSUB1.ANONSTR, consumer_name ADMIN
  postinfo := sys.aq$_post_info('PUBSUB1.ANONSTR:ADMIN',0,HEXTORAW('FF'));
  postinfolist := sys.aq$_post_info_list(postinfo);

  sys.dbms_aq.post(postinfolist, 1);

  commit;

END;
/

Adding an Agent to the LDAP Server

Figure 11-15 Adding an Agent to LDAP

Text description of adque400.gif follows
Text description of the illustration adque400.gif


See Also:

Table 11-1 for a list of operational interface basic operations

Purpose

To add an agent to the LDAP server.

Usage Notes

This call takes an agent and an optional certificate location as the arguments, and adds the agent entry to the LDAP server. The certificate location parameter is the distinguished name of the LDAP entry that contains the digital certificate which the agent will use. If the agent does not have a digital certificate, this parameter will be defaulted to null.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment.

Removing an Agent from the LDAP Server

Figure 11-16 Removing an Agent from LDAP

Text description of adque401.gif follows
Text description of the illustration adque401.gif


See Also:

Table 11-1 for a list of operational interface basic operations

Purpose

To remove an agent from the LDAP server.

Usage notes

This call takes an agent as the argument, and removes the corresponding agent entry in the LDAP server.

Syntax

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment. Use the following syntax references for each programmatic environment:

Examples

See Chapter 3, "AQ Programmatic Environments" for a list of available functions in each programmatic environment.


Go to previous page Go to next page
Oracle
Copyright © 1996, 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback