Previous | Contents | Index |
strcpy(keyvalue, "k"); |
with keyvalue passed as one of the bounds values, then potentially the bound value can differ from one open channel call to the next, because the two bytes following the "k" will contain uninitialized values but still form part of the key-bound definition. (In this case, one should clear the keyvalue buffer before copying the bounds values.)
A call to rtr_open_channel() may be used to create a named partition or to open a server channel associated with an existing named partition. To do this, supply a partition name when opening a server channel. The pkeyseg argument specifies an additional item of type rtr_keyseg_t , assigning the following values:
When using the RTR CLI, if a key-bound value length is less than the key length, the key bound is automatically null-padded to the required length. For example,
Because no key length is specified, the length defaults to four. The low and high bound values are automatically null-padded to four bytes by RTR. |
The key segment array may not contain more than RTR_MAX_NUMSEG elements.
The rtr_open_channel() call opens a channel for communication with other applications on a particular facility.Return Value A value indicating the status of the routine. Possible status values are:The caller of rtr_open_channel() specifies the role (client or server) for which the channel is used.
- Change the rtr_open_channel() call as described in the call description.
- Remove unnecessary SQL calls from server code such as commit or rollback in a two-phase commit environment. If these calls remain in your application code, they may cause vendor-specific warnings.
- RTR allows only one RM instance to be registered for each RTR partition.
- Only one transaction is processed on an RTR channel at any given time. This implies that a server process or a thread of control can only open one channel to handle a single XA request.
- Using a multithreaded server application is strongly recommended for better throughput.
RTR_STS_ACPNOTVIA | RTR ACP no longer a viable entity, restart RTR or application |
RTR_STS_BYTLMNSUFF | Insufficient process quota bytlm, required 100000 |
RTR_STS_DTXOPENFAIL | Distributed transaction request to open a session to the RM has failed |
RTR_STS_DUPLRMNAME | Duplicate RM partition name |
RTR_STS_ERROPEJOU | Error opening journal file |
RTR_STS_INSVIRMEM | Insufficient virtual memory |
RTR_STS_INVACCESS | Invalid access argument |
RTR_STS_INVCHANNEL | Invalid channel argument |
RTR_STS_INVEVTNUM | Invalid evtnum argument |
RTR_STS_INVFACNAM | Invalid facnam argument |
RTR_STS_INVFLAGS | Invalid flags argument |
RTR_STS_INVKSLENGTH | Invalid ks_length argument |
RTR_STS_INVKSTYPE | Invalid ks_type argument |
RTR_STS_INVNUMSEG | Invalid numseg argument |
RTR_STS_INVPKEYSEG | Invalid pkeyseg argument |
RTR_STS_INVRCPNAM | Invalid rcpnam argument |
RTR_STS_INVRMNAME | Invalid resource manager name |
RTR_STS_INVSVRCLIFLG | Either both /Client and /Server flags were supplied or they were missing |
RTR_STS_JOUACCDEN | No access to journal for attempted operation: permission denied |
RTR_STS_JOUNOTFOU | Journal not found |
RTR_STS_MISSINGREQFLG | A required flag is missing |
RTR_STS_NOACP | No RTRACP process available |
RTR_STS_OK | Normal successful completion |
RTR_STS_RMSTRINGLONG | Resource manager open or close string too long |
Examples show the following:
- A simple client application
- A simple server application
- An application using XA
- An application using partition names
Example 3-1 Client Application
rtr_channel_t channel; rtr_status_t status; rtr_string_t user_name; /* Get the user's name through login or other user interface */ user_name = <input data> /* Open client application's channel to the router; * use the facility named `CCardPurchases', and the user's * name to identify this client. * * This client will receive messages only, no events, * and is going to use a foreign transaction manager * that implements the X/Open standard transaction * formats. */ status = rtr_open_channel( &channel, RTR_F_OPE_CLIENT | RTR_F_OPE_FOREIGN_TM, "CCardPurchases", user_name, RTR_NO_PEVTNUM, RTR_NO_ACCESS, RTR_NO_NUMSEG , RTR_NO_PKEYSEG ); check_status(status);
Example 3-2 Server Application
*************************************************************************** /* Open a channel in a server application. This server will * handle only records where the last name begins with A. * It also wants an explicit message sent when it is time * to prepare the transaction, and one when it is time to * vote whether to accept or reject the transaction. */ rtr_channel_t channel; rtr_status_t status; rtr_keyseg_t p_keyseg[1]; rtr_string_t last = "A"; /* * Use this rtr_keyseg_t structure to define this server as * handling only those records whose last name begins * with `A'. */ p_keyseg[0].ks_type = rtr_keyseg_string; p_keyseg[0].ks_length = 1; p_keyseg[0].ks_offset = 0; p_keyseg[0].ks_lo_bound = last; p_keyseg[0].ks_hi_bound = last; /* Open the channel as a server that wants explicit ACCEPT and * PREPARE messages. It is a member of the CcardPurchases * facility, accepts no events (only messages) and we are * sending 1 rtr_keyseg_t structure that defines those * messages to be handled by this server. * * Note also that we are specifying that this channel * will be `XA managed'; that is, the transaction manager * will be one that implements the X/Open standard. */ status = rtr_open_channel( &channel, RTR_F_OPE_SERVER | RTR_F_OPE_EXPLICIT_ACCEPT | RTR_F_OPE_EXPLICIT_PREPARE | RTR_OPE_XA_MANAGED, "CCardPurchases", NULL, RTR_NO_PEVTNUM, RTR_NO_ACCESS, 1, p_keyseg); check_status(status);The snippets from the sample server applications show use of the RM information, the XA flag, and commenting out RM commits and rollbacks.
New XA example, for V4.1 and later
Starting with RTR Version 4.1, when a server application opens a new channel it does not have to specify the RTR_F_OPE_XA_MANAGED flag and RM name along with the RM's attributes such as open_string in order to invoke RTR XA service. The server application just has to specify the name of a partition that is associated with a specific RM, provided that the user specifies an RM name when creating the partition. All transactions processed through this channel will be managed by the RTR XA service.
Impact on Server Application
Using an RTR XA service has some impact on existing server applications, as follows:
- RTR will not present messages of type mt_uncertain to server applications. The server application does not have to replay transactions during the recovery. All transactions will be recovered by RTR when the facility is created.
- The server application does not need to explicitly commit or roll back the transactions with the underlying resource manager because transactions are managed directly by RTR using the XA protocol.
Example 3-3 shows how to open a new channel using RTR V4.1:
Example 3-3 Sample XA Server Application, Version 4.1 and Later
srv_key[0].ks_type = rtr_keyseg_partition; srv_key[0].ks_length = 0; /* N/A */ srv_key[0].ks_offset = 0; /* N/A */ srv_key[0].ks_lo_bound = &partition_name[0]; /* null terminated */ flag = RTR_F_OPE_SERVER | RTR_F_OPE_EXPLICIT_PREPARE | RTR_F_OPE_EXPLICIT_ACCEPT; status = rtr_open_channel(&s_chan, flag, reply_msg.fac_name, NULL, /* rcpnam */ &pevtnum, RTR_NO_ACCESS, num_seg, /* numseg */ srv_key); /* key range */However, if the server application is running a version of RTR prior to RTR V4.0, the server application must specify the RTR_F_OPE_XA_MANAGED flag, the RM's name, and other RM attributes such as open_string . You must overload the rtr_keyset_t data structure with the RM-specific information and then pass it when creating an RTR channel, as shown in Example 3-4.
Example 3-4 Sample XA Server Application Prior to Version 4.1
srv_key[0].ks_type = rtr_keyseg_unsigned; srv_key[0].ks_length = sizeof(rtr_uns_8_t); srv_key[0].ks_offset = 0; srv_key[0].ks_lo_bound = &low; srv_key[0].ks_hi_bound = &high; srv_key[1].ks_type = rtr_keyseg_rmname; srv_key[1].ks_length = 0; /* N/A */ srv_key[1].ks_offset = 0; /* N/A */ srv_key[1].ks_lo_bound = &rm_name[0]; /* null terminated */ srv_key[1].ks_hi_bound = &xa_open_string[0]; /* null terminated */ flag = RTR_F_OPE_SERVER | RTR_F_OPE_EXPLICIT_PREPARE | RTR_F_OPE_EXPLICIT_ACCEPT | RTR_F_OPE_XA_MANAGED; status = rtr_open_channel(&s_chan, flag, reply_msg.fac_name, NULL, /* rcpnam */ &pevtnum, RTR_NO_ACCESS, num_seg, /* numseg */ srv_key); * key range */
Example 3-5 Use of Partition Names
/* Demonstrate use of partition names */ /* */ /* */ #include "rtr.h" #include <stdio.h> main() { /* This program will open a server channel. Servers * need to identify the partition they will be operating * on by passing information coded in the pkeyseg argument. * If the partition already exists and its name is known, * it suffices to specify the partition name. If this is * not the case, then the partition must be specified by * describing the key segments. In the latter case, name * information is optional. If present, the new partition * will receive the specified name, otherwise a default * name will be generated. */ /* */ * This program assumes the presence of a partition named * par_test in the facility fac_test and opens a server * channel to it. Create the partition prior to running * the program, e.g., */ /* */ /* RTR> create partition par_test/facility=fac_test */ /* */ rtr_channel_t AChannel; const char *pszFacilityName = "fac_test"; const char *pszPartitionName = "par_test"; rtr_status_t status; rtr_ope_flag_t flags = RTR_F_OPE_SERVER; rtr_keyseg_t partition_info; partition_info.ks_type = rtr_keyseg_partition; partition_info.ks_lo_bound = (rtr_pointer_t)pszPartitionName; partition_info.ks_hi_bound = NULL; /* Must be NULL */ status = rtr_open_channel( &AChannel, flags, pszFacilityName, RTR_NO_RCPNAM, RTR_NO_PEVTNUM, RTR_NO_ACCESS, 1, &partition_info); /* Call rtr_receive_message() to receive completion status */ }See Also
rtr_close_channel()
rtr_receive_message
Receive a message from RTR or the application.
Syntax
status = rtr_receive_message (pchannel, flags, prcvchan, pmsg, maxlen, timoutms, pmsgsb)
Argument Data Type Access status rtr_status_t write pchannel rtr_channel_t write flags rtr_rcv_flag_t read prcvchan rtr_channel_t read pmsg rtr_msgbuf_t write maxlen rtr_msglen_t read timoutms rtr_timout_t read pmsgsb rtr_msgsb_t write
C Binding
rtr_status_t rtr_receive_message (
rtr_channel_t *pchannel ,
rtr_rcv_flag_t flags ,
rtr_channel_t *prcvchan ,
rtr_msgbuf_t pmsg ,
rtr_msglen_t maxlen ,
rtr_timout_t timoutms ,
rtr_msgsb_t *pmsgsb
)
Arguments
pchannel
The channel identifier on which the message was received.flags
No flags are currently defined. Specify RTR_NO_FLAGS for this parameter.prcvchan
A pointer to a list of channels on which a receive is required. This parameter can be used to select a subset of channels on which messages can be received. Terminate the list with RTR_CHAN_ENDLIST .If no selection is required, that is, a receive from any open channel is acceptable, specify RTR_ANYCHAN for this parameter.
pmsg
Required pointer to the user buffer where the received message is written.maxlen
Size allocated in the user buffer for received messages, in bytes.timoutms
Receive timeout specified in milliseconds. If the timeout expires, the call completes with status RTR_STS_TIMOUT.If no timeout is required, specify RTR_NO_TIMOUTMS .
pmsgsb
Pointer to a message status block describing the received message. The message status block is shown in Example 3-6.
Example 3-6 RTR Message Status Block
typedef struct /* RTR message status block */ { rtr_msg_type_t msgtype; rtr_usrhdl_t usrhdl; rtr_msglen_t msglen; rtr_tid_t tid; rtr_evtnum_t evtnum; } rtr_msgsb_t ;The msgtype field can assume one of the values listed in Table 2-2, RTR Received Message Types for Server Applications and Table 2-3, RTR Received Message Types for Client Applications.
The usrhdl field contains the value supplied with a call to rtr_set_user_handle() .
The msglen field contains the length of the data stored in the user buffer after the call has been executed.
The tid field contains the RTR unique ID for the transaction to which this received message belongs.
The evtnum field contains the event number if the msgtype field is rtr_mt_rtr_event or rtr_mt_user_event.
Description
The rtr_receive_message() call is used to receive a message.Return Value A value indicating the status of the routine. Possible status values are:The caller must have previously opened at least one channel (via rtr_open_channel() or rtr_request_info() ).
By default, this function waits for a message to become available if no message is currently ready to be received.
Upon successful return (RTR_STS_OK), the message status block pointed to by pmsgsb contains the description of the message received.
When a client application calls rtr_send_to_server , RTR sends the message from frontend to router. It is the router's job to find out which key range the message belongs to (by looking at the key field in the application message), and then to forward the message to the backend node where the server application for this key range is running. If the router does not know of a backend that has a server running for this key range, then the router aborts the transaction. In this case, the client application receives an rtr_mt_rejected message for this transaction with status RTR_STS_NODSTFND.
If a client application receives an RTR_STS_NODSTFND error, then the client can try to resend the transaction, as the cause may have been only temporary. Note that the reasons the router cannot find a backend node with an appropriate server include:
- The application server for this key range has not been started.
- The link between the router and backend has gone down.
- In unusual circumstances, a transaction can be rejected with RTR_STS_NODSTFND status after the client calls rtr_accept_tx . This can occur for transactions with multiple participants and no timeout specified where the link between the router (which is quorate) and one of the backend participants has gone down for a period greater than the router's transaction replay timeout period. (This can occur even if the messages in the transaction had all been sent with the RTR_F_SEN_EXPENDABLE flag set.)
RTR_STS_ACPNOTVIA RTR ACP no longer a viable entity, restart RTR or application RTR_STS_BYTLMNSUFF Insufficient process quota bytlm, required 100000 RTR_STS_INVCHANNEL Invalid channel argument RTR_STS_INVFLAGS Invalid flags argument RTR_STS_INVMSG Invalid pmsg argument RTR_STS_INVRMNAME Invalid resource manager name RTR_STS_NOACP No RTRACP process available RTR_STS_NOXACHAN No XA channel available RTR_STS_OK Normal successful completion RTR_STS_SRVDCLSBY Successful server declaration, but as standby RTR_STS_TIMOUT Call to rtr_receive_message timed out RTR_STS_TRUNCATED Buffer too short for msg Message has been truncated
Example
status = rtr_receive_message( &channel, RTR_NO_FLAGS, RTR_ANYCHAN, &receive_msg, sizeof(receive_msg), receive_time_out, &msgsb); check_status( "rtr_receive_message", status ); /* The rtr_msgsb_t tells us what type of * message we are receiving. This server has asked to * be notified when it is time to prepare the transaction. * It should also handle other message types, as well. */ if (msgsb.msgtype == rtr_mt_prepare) { // Do the work necessary to prepare the transaction // before committing.
See Also
rtr_broadcast_event()
rtr_accept_tx()
rtr_open_channel()
rtr_reject_tx()
rtr_send_to_server()
Previous Next Contents Index