4 Oracle Tuxedo /Q COBOL Language Programming
This topic includes the following sections:
4.1 Introduction
This topic provides information about using the ATMI COBOL language functions for enqueuing and dequeuing messages: TPENQUEUE(3cbl) and TPDEQUEUE(3cbl), plus some ancillary functions.
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.2 Prerequisite Knowledge
The Oracle Tuxedo programmer coding client or server programs for the queued message facility should be familiar with the COBOL language binding to the Oracle Tuxedo ATMI. General guidance on Oracle Tuxedo programming is available in Programming Oracle Tuxedo ATMI Applications Using COBOL. Detailed pages on all the ATMI functions are in the Oracle Tuxedo ATMI COBOL Function Reference.
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.3 Where Requests Can Originate
The calls used to place a message on an Oracle Tuxedo /Q queue can originate from any client or server process associated with the application. The list includes:
- Clients or servers on the same machine as the queue space or on another machine on the network
- Conversational programs, although you cannot have a conversational connection with a queue (or with the
TMQUEUE(5)
server) - Workstation clients via a surrogate process on the native side; the administrative interface is also entirely on the native side
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.4 Emphasis on the Default Case
The discussion of Oracle Tuxedo /Q programming in this topic primarily reflects the client-side portion of the figure Queued Service Invocation. The figure shows how a client (or a process acting in the role of a client) queues a message by calling TPENQUEUE(3cbl)
and specifying a queue space made available through a TMQUEUE(5)
server. The client later retrieves a reply via a TPDEQUEUE(3cbl)
call to TMQUEUE
.
The figure illustrates the queued message being dequeued by the server TMQFORWARD(5)
and sent to an application server for processing (through TPCALL(3cbl)
). When a reply to TPCALL
is received, TMQFORWARD
enqueues the reply message. Because TMQFORWARD
provides an interface between the queue space and existing application services, further application coding is not required. For that reason, this topic concentrates on the client-to-queue space side.
Some examples of customization are given after the discussion of the basic model.
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.5 Enqueuing Messages
The syntax for TPENQUEUE() is as follows:
01 TPQUEDEF-REC.
COPY TPQUEDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPENQUEUE" USING TPQUEDEF-REC TPTYPE-REC DATA-REC TPSTATUS-REC.
When a TPENQUEUE()
call is issued it tells the system to store a message on the queue identified inQNAME
in TPQUEDEF-REC
in the space identified in QSPACE-NAME
in TPQUEDEF-REC
. The message is in DATA-REC
, and LEN
in TPTYPE-REC
has the length of the message. By the use of settings in TPQUEDEF-REC, the system is informed how the call to TPENQUEUE()
is to be handled. Further information about the handling of the enqueued message and replies is provided in the TPQUEDEF-REC
structure.
- TPENQUEUE() Arguments
- TPQUEDEF-REC Structure
- Setting a Message Availability Time
- TPENQUEUE() and Transactions
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.5.1 TPENQUEUE() Arguments
There are some important arguments to control the operation of TPENQUEUE(3cbl). Lets look at some of them.
- TPENQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
- TPENQUEUE(): The QNAME in TPQUEDEF-REC Argument
- TPENQUEUE(): The DATA-REC and LEN in TPTYPE-REC Arguments
- TPENQUEUE(): The Settings in TPQUEDEF-REC
Parent topic: Enqueuing Messages
4.5.1.1 TPENQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
QSPACE-NAME
identifies a queue space previously created by the administrator. When a server is defined in the SERVERS
section of the configuration file, the service names it offers are aliases for the actual queue space name (which is specified as part of the OPENINFO
parameter in the GROUPS
section). For example, when your application uses the server TMQUEUE
, the value pointed at by QSPACE-NAME
is the name of a service advertised by TMQUEUE
. If no service aliases are defined, the name of the default service is the same as the server name, TMQUEUE
. In this case the configuration file might include the following:
TMQUEUE
SRVGRP = QUE1 SRVID = 1
GRACE = 0 RESTART = Y CONV = N
CLOPT = "-A"
or
CLOPT = "-s TMQUEUE"
The entry for server group QUE1
has an OPENINFO
parameter that specifies the resource manager, the pathname of the device and the queue space name. The QSPACE-NAME
argument in a client program then looks like this:
01 TPQUEDEF-REC.
COPY TPQUEDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 TPSTATUS-REC.
COPY TPSTATUS.
01 USER-DATA-REC PIC X(100).
*
*
*
MOVE LOW-VALUES TO TPQUEDEF-REC.
MOVE "TMQUEUE" TO QSPACE-NAME IN TPQUEDEF-REC.
MOVE "STRING" TO QNAME IN TPQUEDEF-REC.
SET TPTRAN IN TPQUEDEF-REC TO TRUE.
SET TPBLOCK IN TPQUEDEF-REC TO TRUE.
SET TPTIME IN TPQUEDEF-REC TO TRUE.
SET TPSIGRSTRT IN TPQUEDEF-REC TO TRUE.
MOVE LOW-VALUES TO TPTYPE-REC.
MOVE "STRING" TO REC-TYPE IN TPTYPE-REC.
MOVE LENGTH OF USER-DATA-REC TO LEN IN TPTYPE-REC.
CALL "TPENQUEUE" USING
TPQUEDEF-REC
TPTYPE-REC
USER-DATA-REC
TPSTATUS-REC.
The example shown on the TMQUEUE(5) reference page shows how alias service names can be included when the server is built and specified in the configuration file. The sample program in A Sample Application, also specifies an alias service name.
Parent topic: TPENQUEUE() Arguments
4.5.1.2 TPENQUEUE(): The QNAME in TPQUEDEF-REC Argument
When message queues are being used within a queue space to invoke services, they are named according to application services that process the requests. QNAME
contains such a value; an exception in which QNAME
is not an application service is described in Procedure for Dequeuing Replies from Services Invoked Through TMQFORWARD.
Parent topic: TPENQUEUE() Arguments
4.5.1.3 TPENQUEUE(): The DATA-REC and LEN in TPTYPE-REC Arguments
DATA-REC
contains the message to be processed. LEN
in TPTYPE-REC
gives the length of the message. Some Oracle Tuxedo record types (VIEW
, for example) do not require LEN
to be specified; in such cases, the argument is ignored. If RECTYPE
in TPTYPE-REC
is SPACES
, DATA-REC
and LEN are ignored and the message is enqueued with no data portion.
Parent topic: TPENQUEUE() Arguments
4.5.1.4 TPENQUEUE(): The Settings in TPQUEDEF-REC
TPQUEDEF-REC
are used to tell the Oracle Tuxedo system how the TPENQUEUE()
call is handled; the following are valid settings:
-
TPNOTRAN
- If the caller is in transaction mode and this setting is used, the message is not enqueued within the caller’s transaction. A caller in transaction mode that sets this to true is still subject to the transaction timeout (and no other). If message enqueuing fails that was invoked with this setting, the caller’s transaction is not affected. Either
TPNOTRAN
orTPTRAN
must be set. -
TPTRAN
- If the caller is in transaction mode, this setting specifies that the enqueuing of the message is to be done within the same transaction. Either
TPNOTRAN
orTPTRAN
must be set. -
TPNOBLOCK
- The message is not enqueued if a blocking condition exists. If
TPNOBLOCK
is set and a blocking condition exists such as the internal buffers into which the message is transferred are full, the call fails and tperrno(5) is set toTPEBLOCK
. IfTPNOBLOCK
is set and a blocking condition exists because the target queue is opened exclusively by another application, the call fails,tperrno()
is set toTPEDIAGNOSTIC
, and the diagnostic field of theTPQCTL
structure is set toQMESHARE
. In the latter case, the other application, which is based on an Oracle product other than the Oracle Tuxedo system, opened the queue for exclusive read and/or write using the Queuing Services API (QSAPI). EitherTPNOBLOCK
orTPBLOCK
must be set. -
TPBLOCK
- When
TPBLOCK
is set and a blocking condition exists, the caller blocks until the condition subsides or a timeout occurs (either transaction or blocking timeout). EitherTPNOBLOCK
orTPBLOCK
must be set. -
TPNOTIME
- This setting asks that the call be immune to blocking timeouts; transaction timeouts may still occur. Either
TPNOTIME
orTPTIME
must be set. -
TPTIME
- This setting asks that the call will receive blocking timeouts. Either
TPNOTIME
orTPTIME
must be set. -
TPSIGRSTRT
- This setting says that any underlying system calls that are interrupted by a signal should be reissued. Either
TPSIGRSTRT
orTPNOSIGRSTRT
must be set. -
TPNOSIGRSTRT
- This setting says that any underlying system calls that are interrupted by a signal should not be reissued. The call fails and sets
TP-STATUS
toTPEGOTSIG
. EitherTPSIGRSTRT
orTPNOSIGRSTRT
must be set.
Parent topic: TPENQUEUE() Arguments
4.5.2 TPQUEDEF-REC Structure
The TPQUEDEF-REC
structure has members that are used by the application and by the Oracle Tuxedo system to pass parameters in both directions between application programs and the queued message facility. It is defined in the COBOL COPY
file. The client that calls TPQUEDEF-REC
uses settings to mark members the application wants the system to fill in. The structure is also used by TPDEQUEUE()
; some of the members do not come into play until the application calls that function. The complete structure is shown in the following listing:
Listing 4‑1 The TPQUEDEF-REC Structure
05 TPBLOCK-FLAG PIC S9(9) COMP-5.
88 TPBLOCK VALUE 0.
88 TPNOBLOCK VALUE 1.
05 TPTRAN-FLAG PIC S9(9) COMP-5.
88 TPTRAN VALUE 0.
88 TPNOTRAN VALUE 1.
05 TPTIME-FLAG PIC S9(9) COMP-5.
88 TPTIME VALUE 0.
88 TPNOTIME VALUE 1.
05 TPSIGRSTRT-FLAG PIC S9(9) COMP-5.
88 TPNOSIGRSTRT VALUE 0.
88 TPSIGRSTRT VALUE 1.
05 TPNOCHANGE-FLAG PIC S9(9) COMP-5.
88 TPCHANGE VALUE 0.
88 TPNOCHANGE VALUE 1.
05 TPQUE-ORDER-FLAG PIC S9(9) COMP-5.
88 TPQDEFAULT VALUE 0.
88 TPQTOP VALUE 1.
88 TPQBEFOREMSGID VALUE 2.
05 TPQUE-TIME-FLAG PIC S9(9) COMP-5.
88 TPQNOTIME VALUE 0.
88 TPQTIME-ABS VALUE 1.
88 TPQTIME-REL VALUE 2.
05 TPQUE-PRIORITY-FLAG PIC S9(9) COMP-5.
88 TPQNOPRIORITY VALUE 0.
88 TPQPRIORITY VALUE 1.
05 TPQUE-CORRID-FLAG PIC S9(9) COMP-5.
88 TPQNOCORRID VALUE 0.
88 TPQCORRID VALUE 1.
05 TPQUE-REPLYQ-FLAG PIC S9(9) COMP-5.
88 TPQNOREPLYQ VALUE 0.
88 TPQREPLYQ VALUE 1.
05 TPQUE-FAILQ-FLAG PIC S9(9) COMP-5.
88 TPQNOFAILUREQ VALUE 0.
88 TPQFAILUREQ VALUE 1.
05 TPQUE-MSGID-FLAG PIC S9(9) COMP-5.
88 TPQNOMSGID VALUE 0.
88 TPQMSGID VALUE 1.
05 TPQUE-GETBY-FLAG PIC S9(9) COMP-5.
88 TPQGETNEXT VALUE 0.
88 TPQGETBYMSGIDOLD VALUE 1.
88 TPQGETBYCORRIDOLD VALUE 2.
88 TPQGETBYMSGID VALUE 3.
88 TPQGETBYCORRID VALUE 4.
05 TPQUE-WAIT-FLAG PIC S9(9) COMP-5.
88 TPQNOWAIT VALUE 0.
88 TPQWAIT VALUE 1.
05 TPQUE-DELIVERY-FLAG PIC S9(9) COMP-5.
88 TPQNODELIVERYQOS VALUE 0.
88 TPQDELIVERYQOS VALUE 1.
05 TPQUEQOS-DELIVERY-FLAG PIC S9(9) COMP-5.
88 TPQQOSDELIVERYDEFAULTPERSIST VALUE 0.
88 TPQQOSDELIVERYPERSISTENT VALUE 1.
88 TPQQOSDELIVERYNONPERSISTENT VALUE 2.
05 TPQUE-REPLY-FLAG PIC S9(9) COMP-5.
88 TPQNOREPLYQOS VALUE 0.
88 TPQREPLYQOS VALUE 1.
05 TPQUEQOS-REPLY-FLAG PIC S9(9) COMP-5.
88 TPQQOSREPLYDEFAULTPERSIST VALUE 0.
88 TPQQOSREPLYPERSISTENT VALUE 1.
88 TPQQOSREPLYNONPERSISTENT VALUE 2.
05 TPQUE-EXPTIME-FLAG PIC S9(9) COMP-5.
88 TPQNOEXPTIME VALUE 0.
88 TPQEXPTIME-ABS VALUE 1.
88 TPQEXPTIME-REL VALUE 2.
88 TPQEXPTIME-NONE VALUE 3.
05 TPQUE-PEEK-FLAG PIC S9(9) COMP-5.
88 TPQNOPEEK VALUE 0.
88 TPQPEEK VALUE 1.
05 DIAGNOSTIC PIC S9(9) COMP-5.
88 QMEINVAL VALUE -1.
88 QMEBADRMID VALUE -2.
88 QMENOTOPEN VALUE -3.
88 QMETRAN VALUE -4.
88 QMEBADMSGID VALUE -5.
88 QMESYSTEM VALUE -6.
88 QMEOS VALUE -7.
88 QMEABORTED VALUE -8.
88 QMEPROTO VALUE -9.
88 QMEBADQUEUE VALUE -10.
88 QMENOMSG VALUE -11.
88 QMEINUSE VALUE -12.
88 QMENOSPACE VALUE -13.
88 QMERELEASE VALUE -14.
88 QMEINVHANDLE VALUE -15.
88 QMESHARE VALUE -16.
05 DEQ-TIME PIC 9(9) COMP-5.
05 EXP-TIME PIC 9(9) COMP-5.
05 PRIORITY PIC S9(9) COMP-5.
05 MSGID PIC X(32).
05 CORRID PIC X(32).
05 QNAME PIC X(127).
05 QSPACE-NAME PIC X(127).
05 REPLYQUEUE PIC X(127).
05 FAILUREQUEUE PIC X(127).
05 CLIENTID OCCURS 4 TIMES PIC S9(9) COMP-5.
05 APPL-RETURN-CODE PIC S9(9) COMP-5.
05 APPKEY PIC S9(9) COMP-5.
TPENQUEUE
:
-
TPQTOP
- Setting this value indicates that the queue ordering be overridden and the message placed at the top of the queue. This request may not be granted depending on whether or not the queue was configured to allow overriding the queue ordering. Set
TPQDEFAULT
to use default queue ordering.TPQTOP
,TPQBEFOREMSGID
, orTPQDEFAULT
must be set. -
TPQBEFOREMSGID
- Setting this value indicates that the queue ordering be overridden and the message placed in the queue before the message identified by
MSGID
. This request may not be granted depending on whether or not the queue was configured to allow overriding the queue ordering. SetTPQDEFAULT
to use default queue ordering.TPQTOP
,TPQBEFOREMSGID
, orTPQDEFAULT
must be set. -
TPQTIME-ABS
- If this value is set, the message is made available after the time specified by
DEQ-TIME
.DEQ-TIME
is an absolute time value as generated bytime
(2) ormktime
(3C) (the number of seconds since 00:00:00 Universal Coordinated Time—UTC, January 1, 1970). Set TPQNOTIME if neither an absolute or relative time value is set.TPQTIME-ABS
,TPQTIME-REL
, orTPQNOTIME
must be set. The absolute time is determined by the clock on the machine where the queue manager process resides. -
TPQTIME-REL
- If this value is set, the message is made available after a time relative to the completion of the enqueuing operation.
DEQ-TIME
specifies the number of seconds to delay after the enqueuing completes before the submitted message should be available. SetTPQNOTIME
if neither an absolute or relative time value is set.TPQTIME-ABS
,TPQTIME-REL
, orTPQNOTIME
must be set. -
TPQPRIORITY
- If this value is set, the priority at which the message should be enqueued is stored in
PRIORITY
. The priority must be in the range 1 to 100, inclusive. The higher the number, the higher the priority (that is, a message with a higher number is dequeued before a message with a lower number). For queues not ordered by priority, this value is informational. IfTPQNOPRIORITY
is set, the priority for the message is 50 by default. -
TPQCORRID
- If this value is set, the correlation identifier value specified in
CORRID
is available when a message is dequeued withTPDEQUEUE()
. This identifier accompanies any reply or failure message that is queued so that an application can correlate a reply with a particular request. SetTPQNOCORRID
if a correlation identifier is not available.Note:
The entire 32 bytes of the correlation identifier value are significant, so the value specified inCORRID
must be completely initialized (for example, padded with spaces). -
TPQREPLYQ
- If this value is set, a reply queue named in
REPLYQUEUE
is associated with the queued message. Any reply to the message is queued to the named queue within the same queue space as the request message. SetTPQNOREPLYQ
if a reply queue name is not available. -
TPQFAILUREQ
- If this value is set, a failure queue named in
FAILUREQUEUE
is associated with the queued message. If (1) the enqueued message is processed byTMQFORWARD()
, (2)TMQFORWARD
was started with the -d option, and (3) the service fails and returns a non-NULL reply, a failure message consisting of the reply and its associatedtpurcode
is enqueued to the named queue within the same queue space as the original request message. SetTPQNOFAILUREQ
if a failure queue name is not available. -
TPQDELIVERYQOS TPQREPLYQOS
- If
TPQDELIVERYQOS
is set, the flags specified byTPQUEQOS-DELIVERY-FLAG
control the quality of service for message delivery. One of the following mutually exclusive flags must be set:TPQQOSDELIVERYDEFAULTPERSIST
,TPQQOSDELIVERYPERSISTENT
, orTPQQOSDELIVERYNONPERSISTENT
. IfTPQDELIVERYQOS
is not set,TPQNODELIVERYQOS
must be set. WhenTPQNODELIVERYQOS
is set, the default delivery policy of the target queue dictates the delivery quality of service for the message. -
TPQEXPTIME-ABS
- If this value is set, the message has an absolute expiration time, which is the absolute time when the message will be removed from the queue.
-
TPQEXPTIME-REL
- If this value is set, the message has a relative expiration time, which is the number of seconds after the message arrives at the queue that the message is removed from the queue. The relative expiration time is specified by the value stored in
EXP-TIME
. -
TPQEXPTIME-NONE
- Setting this value indicates that the message should not expire. This flag overrides any default expiration policy associated with the target queue. You can remove a message by dequeuing it or by deleting it via an administrative interface. One of the following must be set:
TPQEXPTIME-ABS
,TPQEXPTIME-REL
,TPQEXPTIME-NONE
, orTPQNOEXPTIME
. -
TPQNOEXPTIME
- Setting this value specifies that the default expiration time associated with the target queue applies to the message. One of the following must be set:
TPQEXPTIME-ABS
,TPQEXPTIME-REL
,TPQEXPTIME-NONE
, orTPQNOEXPTIME
. -
TPQMSGID
- If this value is set and the call to
TPENQUEUE()
is successful, the message identifier is stored inMSGID
. The entire 32 bytes of the message identifier value are significant, so the value stored inMSGID
is completely initialized (for example, padded with null characters). The actual padding character used for initialization varies between releases of the Oracle Tuxedo /Q component. IfTPQNOMSGID
is set, the message identifier is not available. -
[QMEINVAL]
- An invalid setting value was specified.
-
[QMEBADRMID]
- An invalid resource manager identifier was specified.
-
[QMENOTOPEN]
- The resource manager is not currently open.
-
[QMETRAN]
- The call was not in transaction mode or was made with the
TPNOTRAN
setting and an error occurred trying to start a transaction in which to enqueue the message. This diagnostic is not returned by a queue manager from Oracle Tuxedo release 7.1 or later. -
[QMEBADMSGID]
- An invalid message identifier was specified.
-
[QMESYSTEM]
- A system error has occurred. The exact nature of the error is written to a log file.
-
[QMEOS]
- An operating system error has occurred.
-
[QMEABORTED]
- The operation was aborted. If the aborted operation was being executed within a global transaction, the global transaction is marked rollback-only. Otherwise, the queue manager aborts the operation.
-
[QMEPROTO]
- An enqueue was done when the transaction state was not active.
-
[QMEBADQUEUE]
- An invalid or deleted queue name was specified.
-
[QMENOSPACE]
- Due to an insufficient resource, such as no space on the queue, the message with its required quality of service (persistent or non-persistent storage) was not enqueued.
QMENOSPACE
is returned when any of the following configured resources is exceeded:- the amount of disk (persistent) space allotted to the queue space
- the amount of memory (non-persistent) space allotted to the queue space
- the maximum number of simultaneously active transactions allowed for the queue space
- the maximum number of messages that the queue space can contain at any one time
- the maximum number of concurrent actions that the Queuing Services component can handle, or
- the maximum number of authenticated users that may concurrently use the Queuing Services component
-
[QMERELEASE]
- An attempt was made to enqueue a message to a queue manager that is from a version of the Oracle Tuxedo system that does not support a newer feature.
-
[QMESHARE]
- When enqueuing a message from a specified queue, the specified queue is opened exclusively by another application. The other application is one based on an Oracle product other than the Oracle Tuxedo system that opened the queue for exclusive read and/or write using the Queuing Services API (QSAPI).
4.5.2.1 Overriding the Queue Order
If the administrator, in creating a queue, allows TPENQUEUE()
calls to override the order of messages on the queue, you have two mutually exclusive ways to use the override capability. You can specify that the message is to be placed at the top of the queue by setting TPQTOP
or you can specify that it be placed ahead of a specific message by setting TPQBEFOREMSGID
and setting MSGID
to the ID
of the message you wish to precede. This assumes that you saved the message-ID from a previous call in order to be able to use it here. Your administrator must tell you what the queue supports; it can be created to allow either or both of these overrides, or to allow neither.
Parent topic: TPQUEDEF-REC Structure
4.5.2.2 Overriding the Queue Priority
You can set a value in PRIORITY
to specify the priority for the message. The value must be in the range 1 to 100; the higher the number, the higher the priority, unlike values specified with the UNIX nice command. If PRIORITY
was not one of the queue ordering parameters, setting a priority here has no effect on the dequeuing order. The priority value is retained however, so that it can be inspected when the message is dequeued.
Parent topic: TPQUEDEF-REC Structure
4.5.3 Setting a Message Availability Time
You can specify in DEQ-TIME
either an absolute time or a time relative to the completion of the enqueuing operation at which the message is made available. You set either TPQTIME-ABS
or TPQTIME-REL
to indicate how the value should be treated. A queue may be created with time as a queue-ordering criterion, in which case messages are ordered by the message availability time.
The following example illustrates how to enqueue a message with a relative time. The sample message becomes available sixty seconds in the future.
01 TPQUEDEF-REC.
COPY TPQUEDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 TPSTATUS-REC.
COPY TPSTATUS.
01 USER-DATA-REC PIC X(100).
*
*
*
MOVE LOW-VALUES TO TPQUEDEF-REC.
MOVE "QSPACE1" TO QSPACE-NAME IN TPQUEDEF-REC.
MOVE "Q1" TO QNAME IN TPQUEDEF-REC.
SET TPTRAN IN TPQUEDEF-REC TO TRUE.
SET TPBLOCK IN TPQUEDEF-REC TO TRUE.
SET TPTIME IN TPQUEDEF-REC TO TRUE.
SET TPSIGRSTRT IN TPQUEDEF-REC TO TRUE.
SET TPQDEFAULT IN TPQUEDEF-REC TO TRUE.
SET TPQTIME-REL IN TPQUEDEF-REC TO TRUE.
MOVE 60 TO DEQ-TIME IN TPQUEDEF-REC.
SET TPQNOPRIORITY IN TPQUEDEF-REC TO TRUE.
SET TPQNOCORRID IN TPQUEDEF-REC TO TRUE.
SET TPQNOREPLYQ IN TPQUEDEF-REC TO TRUE.
SET TPQNOFAILUREQ IN TPQUEDEF-REC TO TRUE.
SET TPQMSGID IN TPQUEDEF-REC TO TRUE.
MOVE LOW-VALUES TO TPTYPE-REC.
MOVE "STRING" TO REC-TYPE IN TPTYPE-REC.
MOVE LENGTH OF USER-DATA-REC TO LEN IN TPTYPE-REC.
CALL "TPENQUEUE" USING
TPQUEDEF-REC
TPTYPE-REC
USER-DATA-REC
TPSTATUS-REC.
Parent topic: Enqueuing Messages
4.5.4 TPENQUEUE() and Transactions
If the caller of TPENQUEUE()
is in transaction mode and TPTRAN
is set, then the enqueuing is done within the caller's transaction. The caller knows for certain from the success or failure of TPENQUEUE()
whether the message was enqueued or not. If the call succeeds, the message is guaranteed to be on the queue. If the call fails, the transaction is rolled back, including the part where the message was placed on the queue.
If the caller of TPENQUEUE()
is not in transaction mode or if TPNOTRAN
is set, the message is enqueued outside of the caller’s transaction. If the call to TPENQUEUE()
returns success, the message is guaranteed to be on the queue. If the call to TPENQUEUE()
fails with a communication error or with a timeout, the caller is left in doubt about whether the failure occurred before or after the message was enqueued.
Note:
The specifyingTPNOTRAN
while the caller is not in transaction mode has no meaning.
Parent topic: Enqueuing Messages
4.6 Dequeuing Messages
The syntax for TPDEQUEUE()
is as follows:
01 TPQUEDEF-REC.
COPY TPQUEDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPDEQUEUE" USING TPQUEDEF-REC TPTYPE-REC DATA-REC TPSTATUS-REC.
When this call is issued it tells the system to dequeue a message from the QNAME
in TPQUEDEF-REC
queue, in the queue space named QSPACE-NAME
in TPQUEDEF-REC
. The message is placed in DATA-REC
. LEN
in TPTYPE-REC
is set to the length of the data. If LEN
is 0 on return from TPDEQUEUE()
, the message had no data portion. By the use of settings in TPQUEDEF-REC
the system is informed how the call to TPDEQUEUE()
is to be handled.
- TPDEQUEUE() Arguments
- TPDEQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
- TPQUEDEF-REC Structure
- Using TPQWAIT
- Error Handling When Using TMQFORWARD Services
- Procedure for Dequeuing Replies from Services Invoked Through TMQFORWARD
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.6.1 TPDEQUEUE() Arguments
There are some important arguments to control the operation of TPDEQUEUE(3cbl). Let's look at some of them.
Parent topic: Dequeuing Messages
4.6.2 TPDEQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
QSPACE-NAME identifies a queue space previously created by the administrator. When the TMQUEUE server is defined in the SERVERS section of the configuration file, the service names it offers are aliases for the actual queue space name (which is specified as part of the OPENINFO parameter in the GROUPS section). For example, when your application uses the server TMQUEUE, the value pointed at by QSPACE-NAME is the name of a service advertised by TMQUEUE. If no service aliases are defined, the name of the default service is the same as that of the server, TMQUEUE. In this case the configuration file may include the following:
TMQUEUE
SRVGRP = QUE1 SRVID = 1
GRACE = 0 RESTART = Y CONV = N
CLOPT = "-A"
or
CLOPT = "-s TMQUEUE"
The entry for server group QUE1 has an OPENINFO parameter that specifies the resource manager, the pathname of the device, and the queue space name. The QSPACE-NAME argument in a client program then looks like the following:
01 TPQUEDEF-REC.
COPY TPQUEDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 TPSTATUS-REC.
COPY TPSTATUS.
01 USER-DATA-REC PIC X(100).
*
*
*
MOVE LOW-VALUES TO TPQUEDEF-REC.
MOVE "TMQUEUE" TO QSPACE-NAME IN TPQUEDEF-REC.
MOVE "REPLYQ" TO QNAME IN TPQUEDEF-REC.
SET TPTRAN IN TPQUEDEF-REC TO TRUE.
SET TPBLOCK IN TPQUEDEF-REC TO TRUE.
SET TPTIME IN TPQUEDEF-REC TO TRUE.
SET TPSIGRSTRT IN TPQUEDEF-REC TO TRUE.
MOVE LOW-VALUES TO TPTYPE-REC.
MOVE "STRING" TO REC-TYPE IN TPTYPE-REC.
MOVE LENGTH OF USER-DATA-REC TO LEN IN TPTYPE-REC.
CALL "TPDEQUEUE" USING
TPQUEDEF-REC
TPTYPE-REC
USER-DATA-REC
TPSTATUS-REC.
The example shown on the TMQUEUE(5) reference page shows how alias service names can be included when the server is built and specified in the configuration file. The sample program in A Sample Application, also specifies an alias service name.
- TPDEQUEUE(): The QNAME in TPQUEDEF-REC Argument
- TPDEQUEUE(): The DATA-REC and LEN in TPTYPE-REC Arguments
- TPDEQUEUE(): The Settings in TPQUEDEF-REC
Parent topic: Dequeuing Messages
4.6.2.1 TPDEQUEUE(): The QNAME in TPQUEDEF-REC Argument
Queue names in a queue space must be agreed upon by the applications that will access the queue space. This requirement is especially important for reply queues. If QNAME
refers to a reply queue, the administrator creates it (and often an error queue) in the same manner that he or she creates any other queue. QNAME
contains the name of the queue from which to retrieve a message or reply.
Parent topic: TPDEQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
4.6.2.2 TPDEQUEUE(): The DATA-REC and LEN in TPTYPE-REC Arguments
These arguments have a different flavor than they do on TPENQUEUE()
. DATA-REC
is where the system is to place the message being dequeued.
It is an error for LEN
to be 0 on input. When TPDEQUEUE()
returns, LEN
contains the length of the data retrieved. If it is 0, it means that the reply had no data portion. This can be a legitimate and successful reply in some applications; receiving even a 0 length reply can be used to show successful processing of the enqueued request. If you wish to know whether the record has changed from before the call to TPDEQUEUE()
, save the length prior to the call to TPDEQUEUE()
and compare it to LEN
after the call completes. If the reply is larger than LEN
, then DATA-REC
contains only as many bytes as will fit. The remainder are discarded and TPDEQUEUE()
fails with TPTRUNCATE
.
Parent topic: TPDEQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
4.6.2.3 TPDEQUEUE(): The Settings in TPQUEDEF-REC
TPQUEDEF-REC
are used to tell the Oracle Tuxedo system how the TPDEQUEUE()
call is handled; the following are valid settings:
-
TPNOTRAN
- If the caller is in transaction mode, this setting specifies that the message is to be dequeued outside of the caller’s transaction. Either
TPNOTRAN
orTPTRAN
must be set. -
TPTRAN
- If the caller is in transaction mode, this setting specifies that the message is to be dequeued within the same transaction. Either TPNOTRAN or
TPTRAN
must be set. -
TPNOBLOCK
- The message is not dequeued if a blocking condition exists. If
TPNOBLOCK
is set and a blocking condition exists such as the internal buffers into which the message is transferred are full, the call fails and tperrno(5) is set toTPEBLOCK
. IfTPNOBLOCK
is set and a blocking condition exists because the target queue is opened exclusively by another application, the call fails, tperrno() is set toTPEDIAGNOSTIC
, and the diagnostic field of theTPQCTL
structure is set toQMESHARE
. In the latter case, the other application, which is based on an Oracle product other than the Oracle Tuxedo system, opened the queue for exclusive read and/or write using the Queuing Services API (QSAPI). EitherTPNOBLOCK
orTPBLOCK
must be set. -
TPBLOCK
- When
TPBLOCK
is set and a blocking condition exists, the caller blocks until the condition subsides or a timeout occurs (either transaction or blocking timeout). This blocking condition does not include blocking on the queue itself if theTPQWAIT
setting is specified. EitherTPNOBLOCK
orTPBLOCK
must be set. -
TPNOTIME
- Setting this value asks that the call be immune to blocking timeouts; transaction timeouts may still occur. Either
TPNOTIME
orTPTIME
must be set. -
TPTIME
- Setting this value asks that the call receive blocking timeouts. Either TPNOTIME or TPTIME must be set.
-
TPNOCHANGE
- If this value is set, the record type of
DATA-REC
is not allowed to change. That is, the type and subtype of the received record must match the type and subtype of the recordDATA-REC
. EitherTPNOCHANGE
orTPCHANGE
must be set. -
TPCHANGE
- By default, if a record is received that differs in type from the record
DATA-REC
,DATA-REC's
record type changes to the received record's type so long as the receiver recognizes the incoming record type. That is, the type and sub-type of the received record must match the type and sub-type of the recordDATA-REC
. EitherTPNOCHANGE
orTPCHANGE
must be set. -
TPSIGRSTRT
- Setting this value says that any underlying system calls that are interrupted by a signal must be reissued. Either
TPSIGRSTRT
orTPNOSIGRSTRT
must be set. -
TPNOSIGRSTRT
- If this value is set and a signal is received, the call fails and sets
TP-STATUS
toTPEGOTSIG
. EitherTPSIGRSTRT
orTPNOSIGRSTRT
must be set.
Parent topic: TPDEQUEUE(): The QSPACE-NAME in TPQUEDEF-REC Argument
4.6.3 TPQUEDEF-REC Structure
The first argument to TPDEQUEUE()
is the structure TPQUEDEF-REC
. The TPQUEDEF-REC
structure has members that are used by the application and by the Oracle Tuxedo system to pass parameters in both directions between application programs and the queued message facility. The client that calls TPDEQUEUE()
uses settings to mark members the application wants the system to fill in. As described earlier, the structure is also used by TPENQUEUE()
; some of the members only apply to that function. The entire structure is shown in The TPQUEDEF-REC Structure.
As input to TPDEQUEUE()
, the following elements may be set in the TPQUEDEF
structure:
05 MSGID PIC X(32).
05 CORRID PIC X(32).
TPQUEDEF-REC
that control input for TPDEQUEUE()
:
-
TPQGETNEXT
- Setting this value requests that the next message on the queue be dequeued, using the default queue order. One of the following must be set:
TPQGETNEXT
,TPQGETBYMSGID
, orTPQGETBYCORRID
. -
TPQGETBYMSGID
- Setting this value requests that the message identified by
MSGID
be dequeued. The message identifier is returned by a prior call toTPENQUEUE()
. Note that the message identifier is not valid if the message has moved from one queue to another. Note also that the entire 32 bytes of the message identifier value are significant, so the value identified byMSGID
must be completely initialized (for example, padded with spaces). -
TPQWAIT
- Setting this value indicates that an error should not be returned if the queue is empty. Instead, the process should wait until a message is available. Set
TPQNOWAIT
to not wait until a message is available. IfTPQWAIT
is set in conjunction withTPQGETBYMSGID
orTPQGETBYCORRID
, it indicates that an error should not be returned if no message with the specified message identifier or correlation identifier is present in the queue. Instead, the process should wait until a message meeting the criteria is available. The process is still subject to the caller’s transaction timeout, or, when not in transaction mode, the process is still subject to the timeout specified on theTMQUEUE
process by the-t
option. -
TPQPEEK
- If
TPQPEEK
is set, the specified message is read but not removed from the queue. TheTPNOTRAN
flag must be set. It is not possible to read messages enqueued or dequeued within a transaction before the transaction completes.
TPDEQUEUE()
, the following elements may be set in TPQUEDEF-REC
:05 PRIORITY PIC S9(9) COMP-5.
05 MSGID PIC X(32).
05 CORRID PIC X(32).
05 TPQUEQOS-DELIVERY-FLAG PIC S9(9) COMP-5.
05 TPQUEQOS-REPLY-FLAG PIC S9(9) COMP-5.
05 REPLYQUEUE PIC X(127).
05 FAILUREQUEUE PIC X(127).
05 DIAGNOSTIC PIC S9(9) COMP-5.
05 CLIENTID OCCURS 4 TIMES PIC S9(9) COMP-5
05 APPL-RETURN-CODE PIC S9(9) COMP-5.
05 APPKEY PIC S9(9) COMP-5.
The following is a list of valid settings in TPQUEDEF-REC
controlling output information from TPDEQUEUE()
. For any of these settings, if the setting is true when TPDEQUEUE()
is called, the associated element in the record is populated with the value provided when the message was queued, and the setting remains true. If the value is not available (that is, no value was provided when the message was queued) or the setting is not true when TPDEQUEUE()
is called, TPDEQUEUE()
completes with the setting not true.
-
TPQPRIORITY
- If this value is set, the call to
TPDEQUEUE()
is successful, and the message was queued with an explicit priority, then the priority is stored inPRIORITY
. The priority is in the range 1 to 100, inclusive, and the higher the number, the higher the priority (that is, a message with a higher number is dequeued before a message with a lower number). IfTPQNOPRIORITY
is set, the priority is not available. -
TPQMSGID
- If this value is set and the call to
TPDEQUEUE()
is successful, the message identifier is stored inMSGID
. The entire 32 bytes of the message identifier value are significant. IfTPQNOMSGID
is set, the message identifier is not available. -
TPQCORRID
- If this value is set, the call to
TPDEQUEUE()
is successful, and the message was queued with a correlation identifier, then the correlation identifier is stored inCORRID
. The entire 32 bytes of the correlation identifier value are significant. Any Oracle Tuxedo /Q provided reply to a message has the correlation identifier of the original message. IfTPQNOCORRID
is set, the correlation identifier is not available. -
TPQDELIVERYQOS
- If this value is set, the call to
TPDEQUEUE()
is successful, and the message was queued with a delivery quality of service, then the flag—TPQQOSDELIVERYDEFAULTPERSIST
,TPQQOSDELIVERYPERSISTENT
, orTPQQOSDELIVERYNONPERSISTENT
—specified byTPQUEQOS-DELIVERY-FLAG
indicates the delivery quality of service. IfTPQNODELIVERYQOS
is set, the delivery quality of service is not available. -
TPQREPLYQOS
- If this value is set, the call to
TPDEQUEUE()
is successful, and the message was queued with a reply quality of service, then the flag—TPQQOSREPLYDEFAULTPERSIST
,TPQQOSREPLYPERSISTENT
, orTPQQOSREPLYNONPERSISTENT
—specified byTPQUEQOS-REPLY-FLAG
indicates the reply quality of service. IfTPQNOREPLYQOS
is set, the reply quality of service is not available. -
TPQREPLYQ
- If this value is set, the call to
TPDEQUEUE()
is successful, and the message was queued with a reply queue, then the name of the reply queue is stored inREPLYQUEUE
. Any reply to the message should go to the named reply queue within the same queue space as the request message. IfTPQNOREPLYQ
is set, the reply queue is not available. -
TPQFAILUREQ
- If this value is set, the call to
TPDEQUEUE()
is successful, and the message was queued with a failure queue, then the name of the failure queue is stored inFAILUREQUEUE
. Any failure message should go to the named failure queue within the same queue space as the request message. IfTPQNOFAILUREQ
is set, the failure queue is unavailable. -
[QMENOMSG]
- No message was available for dequeuing. Note that it is possible that the message exists on the queue and another application process has read the message from the queue. In this case, the message may be put back on the queue if that other process rolls back the transaction.
-
[QMEINUSE]
- When dequeuing a message by message identifier or correlation identifier, the specified message is in use by another transaction. Otherwise all messages currently on the queue are in use by other transactions. This diagnostic is not returned by a queue manager from Oracle Tuxedo release 7.1 or later.
Parent topic: Dequeuing Messages
4.6.4 Using TPQWAIT
When TPDEQUEUE()
is called with flags set to include TPQWAIT
, if a message is not immediately available, the TMQUEUE
server waits for the arrival, on the queue, of a message that matches the TPDEQUEUE()
request before TPDEQUEUE()
returns control to the caller. The TMQUEUE
process sets the waiting request aside and processes requests from other processes while waiting to satisfy the first request. If TPQGETBYMSGID
and/or TPQGETBYCORRID
are also specified, the server waits until a message with the indicated message identifier and/or correlation identifier becomes available on the queue. If neither of these flags is set, the server waits until any message is put onto the queue. The amount of time it waits is controlled by the caller’s transaction timeout, if the call is in transaction mode, or by the -t option in the CLOPT
parameter of the TMQUEUE
server, if the call is not in transaction mode.
The TMQUEUE
server can handle a number of waiting TPDEQUEUE()
requests at the same time, as long as action resources are available to handle the request. If there are not enough action resources configured for the queue space, TPDEQUEUE()
fails. If this happens on your system, increase the number of action resources for the queue space.
Parent topic: Dequeuing Messages
4.6.5 Error Handling When Using TMQFORWARD Services
In considering how best to handle errors when dequeuing it is helpful to differentiate between two types of errors:
- Errors encountered by TMQFORWARD(5) as it attempts to dequeue a message to forward to the requested service
- Errors that occur in the service that processes the request
By default, if a message is dequeued within a transaction and the transaction is rolled back, then the message ends up back on the queue and can be dequeued and executed again. It may be desirable to delay for a short period before retrying to dequeue and execute the message, allowing the transient problem to clear (for example, allowing for locks in a database to be released by another transaction). Normally, a limit on the number of retries is also useful to ensure that an application flaw doesn't cause significant waste of resources. When a queue is configured by the administrator, both a retry count and a delay period (in seconds) can be specified. A retry count of 0 implies that no retries are done. After the retry count is reached, the message is moved to an error queue that is configured by the administrator for the queue space. If the error queue is not configured, then messages that have reached the retry count are simply deleted. Messages on the error queue must be handled by the administrator who must work out a way of notifying the originator that meets the requirements of the application. The message handling method chosen should be mostly transparent to the originating program that put the message on the queue. There is a virtual guarantee that once a message is successfully enqueued it will be processed according to the parameters of TPENQUEUE()
and the attributes of the queue. Notification that a message has been moved to the error queue should be a rare occurrence in a system that has properly tuned its queue parameters.
A failure queue (normally, different from the queue space error queue) may be associated with each queued message. This queue is specified on the enqueuing call as the place to put any failure messages. The failure message for a particular request can be identified by an application-generated correlation identifier that is associated with the message when it is enqueued.
The default behavior of retrying until success (or a predefined limit) is quite appropriate when the failure is caused by a transient problem that is later resolved, allowing the message to be handled appropriately.
There are cases where the problem is not transient. For example, the queued message may request operating on an account that does not exist (and the application is such that it won't come into existence within a reasonable time period if at all). In this case, it is desirable not to waste any resources by trying again. If the application programmer or administrator determines that failures for a particular operation are never transient, then it is simply a matter of setting the retry count to zero, although this will require a mechanism to constantly clear the queue space error queue of these messages (for example, a background client that reads the queue periodically). More likely, it is the case that some problems will be transient (for example, database lock contention) and some problems will be permanent (for example, the account doesn't exist) for the same service.
In the case that the message is processed (dequeued and passed to the application via a TPCALL
) by TMQFORWARD
, there is no mechanism in the information returned by TPCALL
to indicate whether a TPESVCFAIL
error is caused by a transient or permanent problem.
As in the case where the application is handling the dequeuing, a simple solution is to return success for the service, that is, TPRETURN
with TPSUCCESS
, even though the operation failed. This allows the transaction to be committed and the message removed from the queue. If reply messages are being used, the information in the buffer returned from the service can indicate that the operation failed and the message will be enqueued on the reply queue. The APPL-CODE
in the TPSVCRET-REC
argument of TPRETURN
can also be used to return application specific information.
In the case where the service fails and the transaction must be rolled back, it is not clear whether or not TMQFORWARD
should execute a second transaction to remove the message from the queue without further processing. By default, TMQFORWARD
will not delete a message for a service that fails. TMQFORWARD's
transaction is rolled back and the message is restored to the queue. A command-line option may be specified for TMQFORWARD
that indicates that a message should be deleted from the queue if the service fails and a reply message is sent back with length greater than 0. The message is deleted in a second transaction. The queue must be configured with a delay time and retry count for this to work. If the message is associated with a failure queue, the reply data is enqueued to the failure queue in the same transaction as the one in which the message is deleted from the queue.
Parent topic: Dequeuing Messages
4.6.6 Procedure for Dequeuing Replies from Services Invoked Through TMQFORWARD
If your application expects to receive replies to queued messages, you can follow this procedure:
- As a preliminary step, the queue space must include a reply queue and a failure queue. The application must also agree on the content of the correlation identifier. The service should be coded to return
TPSUCCESS
on a logical failure and return an explanatory code in theAPPL-CODE
in theTPSVCRET-REC
argument ofTPRETURN
. - When you call
TPENQUEUE()
to put the message on the queue, set the following:TPQCORRID
TPQREPLYQ
TPQFAILUREQ
TPQMSGID
(Fill in the values for
CORRID
,REPLYQUEUE
andFAILUREQUEUE
before issuing the call. On return from the call, saveCORRID
.) - When you call
TPDEQUEUE()
to check for a reply, specify the reply queue inQNAME
and set the following:TPQCORRID TPQREPLYQ TPQFAILUREQ TPQMSGID TPQGETBYCORRID
(Use the saved correlation identifier to populate
CORRID
before issuing the call. If the call toTPDEQUEUE()
fails and setsTP-STATUS
toTPEDIAGNOSTIC
, then further information is available in theDIAGNOSTIC
settings. If you receive the error codeQMENOMSG
, it means that no message was available for dequeuing.) - Set up another call to
TPDEQUEUE()
. This time haveQNAME
point to the name of the failure queue and set the following:TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
TPQGETBYCORRIDPopulate
TPQCORRID
with the correlation identifier. When the call returns, checkLEN
to see if data has been received and checkAPPL-RETURN-CODE
to see if the service has returned a user return code.
Parent topic: Dequeuing Messages
4.7 Sequential Processing of Messages
Sequential processing of messages can be achieved by having one service enqueue a message for the next service in the chain before its transaction is committed. The originating process can track the progress of the sequence with a series of TPDEQUEUE()
calls to the reply_queue
, if each member uses the same correlation-ID and returns a 0 length reply.
Alternatively, word of the successful completion of the entire sequence can be returned to the originator by using unsolicited notification. To make sure that the last transaction in the sequence ended with a TPCOMMIT
, a job step can be added that calls TPNOTIFY
using the client identifier that is carried in the TPQUEDEF-REC
structure. The originating client must have called TPSETUNSOL
to name the unsolicited message handler being used.
Parent topic: Oracle Tuxedo /Q COBOL Language Programming
4.7.1 Using Queues for Peer-to-Peer Communication
In all of the foregoing discussion of enqueuing and dequeuing messages there has been an implicit assumption that queues were being used as an alternative form of request/response processing. A message does not have to be a service request. The queued message facility can transfer data from one process to another as effectively as a service request. This style of communication between applications or clients is called peer-to-peer communication.
If it suits your application to use Oracle Tuxedo /Q for this purpose, have the administrator create a separate queue and code your own receiving program for dequeuing messages from that queue.
Parent topic: Sequential Processing of Messages