Reliable Transaction Router
Application Design Guide


Previous Contents Index

Processing Summary

This section summarizes the default behavior of the client and server transaction controller objects when they interact in processing a transaction. When a transaction controller receives an RTRData object, it receives an RTR message. With the event-driven model of processing, Dispatch is automatically called and the appropriate methods, based on the RTR message, execute by default. For tables of the RTR to C++ API mapping of messages and events, see the Reliable Transaction Router C++ Foundation Classes manual. Table 4-2 lists commonly used server transaction controller methods.

Table 4-2 RTRServerTransactionControllerMethods
ServerTransactionController RTR Message within RTRData Event- Driven Default Calls Default Behavior
RTRServerTransactionController::
RegisterPartition()
NA (not applicable) NA Creates a partition.
RTRServerTransactionController::
RegisterHandlers()
NA NA Registers server message and event handlers with the server transaction controller.
RTRServerTransactionController::
Receive()
rtr_mt_msg1 OnInitialize
OnApplicationMessage
Receives application message.
RTRServerTransactionController::
Receive()
rtr_mt_msgn OnApplicationMessage Receives application message.
RTRServerTransactionController::
SendApplicationMessage()
NA NA Sends application message.
RTRServerTransactionController::
Receive()
rtr_mt_prepare OnPrepare Receives application message.
RTRServerTransactionController::
AcceptTransaction
NA NA Accepts transaction.
RTRServerTransactionController::
Receive()
rtr_mt_accepted OnAccepted Receives application message.
RTRServerTransactionController::
Receive()
rtr_mt_rejected OnRejected Receives application message.

To register two partitions, create two partitions and call Register once for each. Table 4-3 lists basic client transaction controller methods.

Table 4-3 RTRClientTransactionController Methods
ClientTransactionController RTR Message within RTRData Event- Driven Default Calls
RTRClientTransactionController:: Receive() rtr_mt_reply RTRServerMessageHandler:: (OnInitialize)
RTRServerMessageHandler::
(OnApplicationMessage)
RTRClientTransactionController:: AcceptTransaction() rtr_mt_accept  
RTRClientTransactionController:: Receive() rtr_mt_accepted OnAccepted

For more information on RTRTransactionController methods, see the Reliable Transaction Router C++ Foundation Classes manual.

Administering Transaction Timeouts

RTR provides a relatively simple way to administer a transaction timeout in the server. Use of timeout values on the Receive() method lets a server application specify how long it is prepared to wait for the next message. (Of course, the server should be prepared to wait forever to get a new transaction or for the result of an already-voted transaction.)

One way to achieve this would be to have a transaction controller-specific global variable, say, called SERVER_INACTIVITY_TIMEOUT , which is set to the desired value (in milliseconds-that is, use a value of 5000 to set a 5-second timeout). Note that this timeout value should be used after receiving the first message of the transaction. The value should be reset to RTR_NO_TIMOUTMS after receiving the rtr_mt_prepare message. Whenever the Receive method completes with an RTR_STS_TIMOUT , the server transaction controller calls RejectTransaction to abort the partially processed transaction. This would prevent transactions from occupying the server process beyond a reasonable time.

Two-Phase Commit

A prepared application votes its intention using the AcceptTransaction method. An application that does not agree to commit to this transaction votes with the RejectTransaction method. This is the first (or prepare) phase of the two-phase commit process.

Initiating the Prepare Phase

The two-phase commit process with the C++ API is initiated by the client application when it issues a call to RTR indicating that the client "accepts" the transaction. This does not mean that the transaction is fully accepted, only that the client is prepared to accept it. RTR then asks the server applications participating in the transaction if they are prepared to accept the transaction. A server application that is prepared to accept the transaction votes its intention by issuing the AcceptTransaction method, an "accept" vote. A server application that is not prepared to accept the transaction issues the RejectTransaction method, a "not accept" vote. Issuing all votes concludes the prepare phase.

RTR provides an optional message to the server, OnPrepareTransaction, to expose the prepare phase. This message indicates to the server that it is time to prepare any updates for a later commit or rollback operation.

Commit Phase

In the second phase of the commit, RTR collects votes from all the servers. If they are all votes to accept, then RTR tells all participant servers that they can now commit the transaction to the database. RTR also informs the client that the transaction has completed successfully. If any server rejects the transaction, all participants are informed of this and the database is left unchanged. Your application can use the level of participation that makes the most sense for your business and operations needs.

Explicit Accept, Explicit Prepare

To request an explicit accept and explicit prepare of transactions, the server receives both prepare and accept messages. The server then explicitly accepts or rejects a transaction when it receives the prepare message. The transaction sequence for an explicit prepare and explicit accept is as follows:
Client RTR Server
SendApplicationMessage -> rtr_mt_msg1 -> Receive
AcceptTransaction -> rtr_mt_prepare -> Receive
    <- AcceptTransaction
Receive <- rtr_mt_accepted -> Receive

With explicit transaction handling, the following steps occur:

A participant can reject the transaction up to the time RTR has sent the rtr_mt_prepare message to the server using the AcceptTransaction method and the AcceptTransaction method is executed. Once the client application has used the AcceptTransaction method, the result cannot be changed.

Implicit Prepare, Explicit Accept

The sequence for an implicit prepare and explicit accept is as follows:
Client RTR Server
SendApplicationMessage -> rtr_mt_msg1 -> Receive
AcceptTransaction -> <- AcceptTransaction
Receive <-rtr_mt_accepted -> Receive

In certain database applications, where the database manager does not let an application explicitly prepare the database, transactions can simply be accepted or rejected. For server optimization, the server can signal its acceptance of a transaction with either the SetAcceptTransaction method, or with the client calling the SetAcceptTransaction method. This helps minimize network traffic for transactions by increasing the likelihood that the data message and the RTR accept message will be sent in the same network packet.

Server Transaction States

The server transaction states depend on whether the transaction is in prepare or commit phase. Table 4-4 lists server transaction states in the prepare phase.

Table 4-4 Prepare Phase Server States
State Meaning
RECEIVING This state represents the server not yet voting on the transaction.
VOTING The transaction state changes to VOTING when the client has accepted the transaction and RTR has asked the server to vote but the server has not yet answered.
Table 4-5 lists server transaction states in the commit phase.

Table 4-5 Commit Phase Server States
State Meaning
COMMIT The server commits the transaction after receiving a message from RTR. If all servers vote to accept (AcceptTransaction), all participants receive a commit message.
ABORT The server aborts the transaction after receiving a message from RTR. If any server votes to abort (RejectTransaction), all participants receive an abort message.

Router Transaction States

The transaction states for the router depend on whether the transaction is in prepare or commit phase. Table 4-6 lists states in the prepare phase.

Table 4-6 Prepare Phase Router States
State Meaning
SENDING The router state changes to VREQ except on a failed transaction, in which case it changes to ABORTING.
VREQ This state represents RTR waiting for the server to vote by issuing AcceptTransaction or RejectTransaction. Once a vote is received, the state changes to either COMMITTING or ABORTING.

Transaction Recovery

When a transaction fails in progress, RTR provides recovery support using RTR replay technology. RTR, as a distributed transaction manager, communicates with a database resource manager in directing the two-phase commit process. Table 4-7 lists the typical server application transaction sequences for committing a transaction to the database. The sequence depends on which processing model you implement, polling or event driven.

Table 4-7 Typical Server Application Transaction Sequences
Polling Model Event-Driven Model
1. RTRServerTransactionController::
Receive(rtr_mt_msg1)
1. RTRServerTransactionController::
Receive(rtr_mt_msg1)
2. SQL update 2. RTRServerMessageHandler::
OnInitialize()
3. RTRServerTransactionController::
AcceptTransaction()
3. RTRServerMessageHandler::
OnApplicationMessage()
4. RTRServerTransactionController::
Receive(rtr_mt_accepted)
4. SQL update
5. SQL commit 5. RTRServerTransactionController::
AcceptTransaction()
6. RTRServerTransactionController::
AcknowledgeTransactionOutcome()
6. RTRServerTransactionController::
Receive(rtr_mt_accepted)
  7. RTRServerMessageHandler::
OnAccepted()
  8. SQL commit
  9. RTRServerTransactionController::
AcknowledgeTransactionOutcome()

Recovery Examples

The impact of a crash on application recovery depends on where in the process the crash occurs. RTR handles the recovery, with the assistance of the application.

The typical server application transaction sequence using the event-driven processing model is as follows:

  1. Receive(OnInitialize,
    OnApplicationMessage)
  2. SQL update
  3. AcceptTransaction
  4. Receive(OnAccepted)
  5. SQL commit
  6. AcknowledgeTransactionOutcome

RTR transaction recovery summarized:

Recovery: Before Server Accepts

If the failure occurs before the server accepts a transaction, the sequence is as follows:

  1. Receive(OnInitialize, OnApplicationMessage)
    failure
  2. SQL update
  3. AcceptTransaction
  4. Receive(OnAccepted)
  5. SQL commit
  6. Receive

If a crash occurs before the server accepts a transaction (between steps 1 and 3):

If another server (concurrent or standby) is available, RTR replays the transaction to that other server.

Recovery: After Server Accepts

If the failure occurs after a server accepts a transaction, the sequence is as follows:

  1. Receive(OnInitialize, OnApplicationMessage)
  2. SQL update
  3. AcceptTransaction
    failure
  4. Receive(OnAccepted)
    failure
  5. SQL commit
  6. Receive

If a failure occurs after the AcceptTransaction method is executed, but before the SQL Commit, the transaction is replayed. The type of the first message is then rtr_mt_uncertain when the server is restarted. Servers should check to see if the transaction has already been executed in a previous presentation. If not, it is safe to re-execute the transaction because the database operation never occurred.

After the failure where the server accepts a transaction, but before the database is committed (between steps 3 and 5) the following occurs:

If a failure occurs after the transaction has been accepted, but before it has been committed, the message is rtr_mt_uncertain when the server is restarted. It is safe to re-execute the transaction since the database commit operation never occurred.

Recovery: After Database is Committed

If the failure occurs after the database is committed (for example, after the SQL commit but before receipt of a message starting the next transaction), RTR does not know the difference. The sequence is as follows:

If failure occurs after an SQL commit is made, but before the receipt of a message starting the next transaction (between steps 5 and 6), the sequence is as follows:

In this case, the transaction should not be re-executed because the database commit operation has already occurred.

Recovery: After Beginning a New Transaction

If the failure occurs after executing a Receive method to begin a new transaction, RTR assumes a successful commit (if the Receive occurs after receiving the rtr_mt_accepted message) and will forget the transaction. There is no replay following these events. The sequence is as follows:

  1. Receive(OnInitialize, OnApplicationMessage)
  2. SQL update
  3. AcceptTransaction
  4. Receive(OnAccepted)
  5. SQL commit
  6. Receive
    failure

If a crash occurs after a Receive call is made to begin a new transaction (after step 6), the sequence is as follows:

As an application design suggestion, the application can maintain the list of transaction identifiers (TID) on a per-process, per-transaction controller basis to keep the list from growing infinitely.

Exception Transaction Handling

RTR keeps track of how many times a transaction is presented to a server application before it is VOTED. The rule is: three strikes and you're out! After the third strike, RTR rejects the transaction with the reason RTR_STS_SRVDIED . The server application has committed the transaction and the client believes that the transaction is committed. The transaction is flagged as an exception and the database is not committed. Such an exception transaction can be manually committed if necessary. This process eliminates the possibility that a single rogue transaction can crash all available copies of a server application at both primary and secondary sites.

Application design can change this behavior. The application can specify the retry count to use when in recovery using the SetRecoveryRetryCount method in the RTRBackEndPartitionProperties class, or the system administrator can set the retry count from the RTR CLI with the SET PARTITION command. If no recovery retry count is specified, RTR retries replay three times. For recovery, retries are infinite. For more information on the SET PARTITION command, see the Reliable Transaction Router System Manager's Manual; for more information on the SetRecoveryRetryCount method, see the Reliable Transaction Router C++ Foundation Classes manual.

When a node is down, the operator can select a different backend to use for the server restart. To complete any incomplete transactions, RTR searches the journals of all backend nodes of a facility for any transactions for the key range specified in the server's RegisterPartition call.

Coordinating Transactions

RTR provides two mechanisms for coordinating RTR transactions with database transactions (or database managers): transaction management coordination (XA, DECdtm) and RTR replay technology.

Integration of RTR with Resource Managers

When RTR is used with a resource manager (database or DB manager), two transactions are defined: an RTR transaction and that of the resource manager. These must be coordinated to ensure that a transaction committed by the resource manager is also committed by RTR. The same applies to rejected transactions.

Distributed Transaction Model

A distributed transaction manager provides a link for RTR to communicate with the resource manager in directing the two-phase commit process. Without the transaction manager, there is no path for RTR to communicate with a resource manager, so RTR must rely on the application for this communication. In general, two-phase commit coordination with the resource manager is not available to application programs.

Without a transaction manager, RTR uses replay technology to handle coordination with a resource manager. With a transaction manager, the transaction manager is the common agent to link the two transactions.


Previous Next Contents Index