Previous | Contents | Index |
Figure C-1 shows server states after delivery of a primary or secondary event, and message types used with primary and secondary servers.
Figure C-1 Server Events and States with Active Transaction Message Types
Figure C-2 shows server states after delivery of a standby event, and message types used with transactions that are active or in recovery.
Figure C-2 Server States after Standby Events
The application must specify server type with boolean attributes using the CreateBackEndPartition method in the RTRManager class. For example, the following declaration establishes a standby server with concurrency:
CreateBackEndPartition( *pszPartitionName, pszFacility, pKeySegment bShadow=false bConcurrent=true bStandby=true); |
To add a transactional shadow server, use: bShadow = true
To disallow a standby server, use: bStandby = false
With the C++ API, you enable RTR failover behavior with the CreateBackEndPartition method in the RTRPartitionManager management class.
For the C++ API, concurrent servers can be implemented as many server transaction controllers in one process or as one or many server transaction controllers in many processes.
RTR delivers transactions to any open transaction controllers, so each application thread must be ready to receive and process transactions.
An application creates a transaction controller and registers a partition with the RegisterPartition method. To specify whether or not a server is concurrent, the application uses the CreateBackendPartition method in the RTRPartitionManager class. The rules are as follows:
For example, the following declaration establishes a concurrent server that is also a standby:
CreateBackEndPartition( *pszPartitionName, pszFacility, pKeySegment bShadow=false bConcurrent=true bStandby=true); |
The following declaration establishes a server with no concurrency:
CreateBackEndPartition( *pszPartitionName, pszFacility, pKeySegment bShadow=false bConcurrent=false bStandby=true); |
For more information on the CreateBackEndPartition method, see the Reliable Transaction Router C++ Foundation Classes manual.
RTR manages the activation of standby servers at run time.
When an application creates a server partition with the CreateBackEndPartition method in the RTRPartitionManager class, it specifies whether a server is to be standby or not as follows:
CreateBackEndPartition ( *pszPartitionName, pszFacilityName, *pKeySegment, bShadow = false, bConcurrent = true, bStandby = false); |
When an application creates a server partition with the CreateBackEndPartition method in the RTRPartitionManager class, it specifies whether a server is to be a shadow or not as follows:
CreateBackEndPartition ( *pszPartitionName, pszFacilityName, *pKeySegment, bShadow = true, bConcurrent = true, bStandby = false); |
Only one primary and one secondary shadow server can be established. Shadow servers can have both standby and concurrent servers.
When partition state is important to an application, the application can determine if a shadow server is in the primary or secondary partition state after server restart and recovery following a server failure. The application does this using methods in the RTRServerEventHandler class such as OnServerIsPrimary, OnServerIsStandby, and OnServerIsSecondary. For example:
OnServerIsPrimary(*pRTRData, *pController); |
Within your application server code, you identify those transactions that can be considered independent, and set the state of the transaction controller object with the bIndependent attribute in the AcceptTransaction method, as appropriate. The following example illustrates how to set the bIndependent parameter to true with the AcceptTransaction method to make a transaction independent.
RTRServerTransactionController *pController= new RTRServerTransactionController(); pController->AcceptTransaction(RTR_NO_REASON, true); |
Another example:
RTRServerTransactionController stc; /* Determine from our business logic if this transaction is independent of our other transactions. */ If (true == Independent()) { stc.AcceptTransaction(RTR_NO_REASON,true) } else { stc.AcceptTransaction() } |
The application specifies the server type in the rtr_open_channel call as follows:
rtr_status_t rtr_open_channel ( . rtr_ope_flag_t |
To add a transactional shadow server, include the following flags: flags = RTR_F_OPE_SERVER RTR_F_OPE_SHADOW;
To disallow concurrent and standby servers, use the following flags:
flags = RTR_F_OPE_SERVER | RTR_F_OPE_NOCONCURRENT | RTR_F_OPE_NOSTANDBY; |
With the C API, you enable RTR failover behavior with flags set when your application executes the rtr_open_channel statement or command.
For the C API, concurrent servers can be implemented as many channels in one process or as one or many channels in many processes. By default, a server channel is declared as concurrent.
RTR delivers transactions to any open channels, so each application thread must be ready to receive and process transactions. The main constraint in using concurrent servers is the limit of available resources on the machine where the concurrent servers run.
When an application opens a channel with the rtr_open_channel call, it specifies whether the server is to be concurrent or not, as follows:
For example, the following code fragment establishes a server with concurrency:
rtr_open_channel(&Channel, RTR_F_OPE_SERVER, FACILITY_NAME, NULL, RTR_NO_PEVTNUM, NULL, Key.GetKeySize(), Key.GetKey() != RTR_STS_OK); |
If an application starts up a second server for a partition on the same node, the second server is a concurrent server by default.
The following example establishes a server with no concurrency:
rtr_open_channel(&Channel, RTR_F_OPE_SERVER|RTR_F_OPE_NOCONCURRENT, FACILITY_NAME, NULL, RTR_NO_PEVTNUM, NULL, Key.GetKeySize(), Key.GetKey() != RTR_STS_OK); |
When a concurrent server fails, the server application can fail over to another running concurrent server, if one exists.
Concurrent servers are useful both to improve throughput using multiple channels on a single node, and to make process failover possible. Concurrent servers can also help to minimize timeout problems in certain server applications. For more information on this topic, see the section later in this manual on Server-Side Transaction Timeouts.
For more information on the rtr_open_channel call, see the Reliable Transaction Router C Application Programmer's Reference Manual and the discussion later in this document.
RTR manages the activation of standby servers at run time.
When an application opens a channel, it specifies whether or not the server is to be standby, as follows:
When an application opens a channel, it specifies whether the server is to have the capability to be a transactional shadow server or not, as follows:
Only one primary and one secondary shadow server can be established. Shadow servers can have both standby and concurrent servers.
When partition state is important to an application, the application can determine if a shadow server is in the primary or secondary partition state after server restart and recovery following a server failure. The application does this using RTR events in the rtr_open_channel call, specifying the events RTR_EVTNUM_SRPRIMARY and RTR_EVTNUM_SRSECONDARY . For example, the following is the usual rtr_open_channel declaration:
rtr_status_t rtr_open_channel ( rtr_channel_t *p_channel, //Channel rtr_ope_flag_t flags, //Flags rtr_facnam_t facnam, //Facility rtr_rcpnam_t rcpnam, //Name of the channel rtr_evtnum_t *p_evtnum, //Event number list //(for partition states) rtr_access_t access, //Access password rtr_numseg_t numseg, //Number of key segments rtr_keyseg_t *p_keyseg //Pointer to key-segment data ) |
To enable receipt of RTR events that show shadow state, used if an application needs to include logic depending on partition state, the application enables receipt of RTR events that show shadow state.
The declaration includes the events as follows:
rtr_evtnum_t evtnum = { RTR_EVTNUM_RTRDEF, RTR_EVTNUM_SRPRIMARY, RTR_EVTNUM_SRSECONDARY, RTR_EVTNUM_ENDLIST }; rtr_evtnum_t *p_evtnum = &evtnum; |
Broadcasts deliver using name and subscription name. For details, see the descriptions of rtr_open_channel and rtr_broadcast_event in the RTR C Application Programmer's Reference Manual.
Within your application server code, you identify those transactions that can be considered independent, and process them with the independent transaction flags on rtr_accept_tx or rtr_reply_to_client calls, as appropriate. For example, the following code fragment illustrates use of the independent transaction flag on the rtr_accept_tx call:
case rtr_mt_prepare: /* if (txn is independent).*/ status = rtr_accept_tx (channel, RTR_F_ACC_INDEPENDENT, RTR_NO_REASON\\); if (status != RTR_STS_OK) |
You can also use the independent flag on the rtr_reply_to_client call. For example,
rtr_reply_to_client(channel, RTR_F_REP_INDEPENDENT, pmsg, msglen, msgfmt); |
For example, the following snippet specifies named events for all subscribers:
rtr_status_t rtr_open_channel { . rtr_rcpnam_t rcpnam = "*"; rtr_evtnum_t evtnum = { RTR_EVTNUM_USERDEF, RTR_EVTNUM_USERBASE, RTR_EVTNUM_UP_TO, RTR_EVTNUM_USRMAX, RTR_EVTNUM_ENDLIST }; rtr_evtnum_t *p_evtnum = &evtnum; |
For a broadcast to be received by an application, the recipient name specified by the subscribing application on its rtr_open_channel call must match the recipient specifier used by the broadcast sender on the rtr_broadcast_event call.
RTR_NO_RCPSPC is not the same as "*". |
An application receives broadcasts with the rtr_receive_message call. A message type returned in the message status block informs the application of the type of broadcast received.
For example,
rtr_receive_message(.pmsg,maxlen,.pmsgsb); |
The user event would be in msgsb.msgtype == rtr_mt_user_event . User broadcasts can also contain a broadcast message. This message is returned in the message buffer provided by the application. The size of the user's buffer is determined by the maxlen field. The number of bytes actually received is returned by RTR in the msglen field of the message status block.
An application subscribes to an RTR event with the rtr_open_channel call. For example,
rtr_status_t rtr_open_channel( . rtr_rcpnam_t rcpnam = RTR_NO_RCPNAM; rtr_evtnum_t evtnum = { RTR_EVTNUM_RTRDEF, RTR_EVTNUM_SRPRIMARY, RTR_EVTNUM_ENDLIST }; rtr_evtnum_t *p_evtnum = &evtnum; ) |
You read the message type to determine what RTR has delivered. For example,
rtr_status_t rtr_receive_message ( . rtr_msgsb_t *p msgsb ) |
Use a data structure of the following form to receive the message:
typedef struct { rtr_msg_type_t msgtype; rtr_usrhdl_t usrhdl; rtr_msglen_t msglen; rtr_tid_t tid; rtr_evtnum_t evtnum; /*Event Number*/ } rtr_msgsb_t; |
The event number is returned in the message status block in the evtnum field. The following RTR events return key range data back to the client application:
RTR_EVTNUM_KEYRANGEGAIN RTR_EVTNUM_KEYRANGELOSS |
These data are included in the message ( pmsg ); size is msglen_sizeof(rtr_msgsb_t) . Other events do not have additional data.
Use the following brief checklist to help diagnose a particular performance problem:
Excessive use of a MONITOR command can be disruptive to the system. For example, running several MONITOR commands simultaneously steals cycles away from RTR to do real work. To minimize the impact of using MONITOR commands, increase the sample size interval using /INTERVAL= no-of-seconds . |
Previous | Next | Contents | Index |