Structuring distributed transactions

As with many design problems, designing a DTP application involves dealing with several conflicting objectives that must be carefully balanced against each other. These include performance, ease of maintenance, reliability, security, connectivity to existing functions, and recovery.

Avoiding performance problems

If performance is the highest priority, you should design your application so that data is processed as close to its source as possible. This avoids unnecessary transmission of data across the network. Alternatively, if processing can be deferred, you may wish to consider batching data locally before transmitting.

To maintain performance across the intersystem connection, the conversation should be freed as soon as possible -- so that the session may be used by other transactions. In particular, avoid holding a conversation across a terminal wait.

In terminal-attached transactions, pseudo-conversational design improves performance by reducing the amount of time a transaction holds CICS® resources. This is because a terminal user is likely to take seconds or even minutes to respond to any request for keyboard input. In contrast, the communication delay associated with a conversation between partner transactions is likely to be only a few milliseconds. It is therefore not necessary to terminate a front-end transaction pending a response from a back-end transaction.

However, a front-end transaction can be terminal-initiated, in which case a pseudo-conversational design may be appropriate. When input from the terminal user is required, the front-end transaction and its conversations should be terminated. After the terminal user has responded, the successor front-end transaction can initiate a successor back-end transaction. If the first back-end transaction needs to pass information to its successor, the information must either be passed to the front-end transaction or stored locally (for example, in temporary storage).

Stored information should be retrievable by identifiers that are not associated with the particular session used by the conversation. The back-end transaction cannot use a COMMAREA, a RETURN TRANSID, nor a TCTUA for this purpose. Instead, it can construct the identifier of a temporary-storage queue by using information obtained from the front-end transaction. The sysid of the principal facility, and the identifier of the terminal to which the front-end transaction is attached, can be used.

Making maintenance easier

To correct errors or to adapt to the evolving needs of an organization, distributed processes inevitably need to be modified. Whether these changes are made by the original developers or by others, this task is likely to be easier if the distributed processes are relatively simple. So consider minimizing the number of transactions involved in a distributed process.

Going for reliability

If you are particularly concerned with reliability, consider minimizing the number of transactions in the distributed process.

Protecting sensitive data

If the distributed process is to handle security-sensitive data, you could place this data on a single system. This means that only one of the transactions needs knowledge of how or where the sensitive data is stored. For guidance on implementing security in CICS systems, see the CICS RACF® Security Guide.

Maintaining connectivity

If you require connectivity to transactions running in a back-level CICS system, check the appropriate books for that release to ensure that the functions required are compatible.

The following aspects of distributed process design differ from single-system considerations:

Data conversion
For non-EBCDIC APPC logical units (for example, CICS OS/2), some data conversion may be required on either receipt or sending of data.
Using multiple conversations
When using multiple, serial conversations, note that different conversation identifiers may be provided to the transaction (by CICS). It is therefore not advisable to use the conversation identifier for naming resources (for example, temporary storage queues).

Safeguarding data integrity

If it is important for you to be able to recover your data when things go wrong, design conversations for sync level 2, and keep the units of work as small as possible. However, this is not always possible, because the size of a UOW is determined largely by the function being performed. Remember that CICS syncpoint processing has no information about the structure and purpose of your application. As an application designer, you must ensure that syncpoints are taken at the right time and place, and to good purpose. If you do, error conditions are unlikely to lead to inconsistencies in recoverable data resources.

Here is an example of a distributed application that transfers the contents of a temporary storage queue from system A to system B, using a pair of transactions (TRAA in system A, and TRBB in system B), and a conversation at synclevel 2.

  1. Transaction TRAA in system A reads a record from the temporary storage queue.
  2. Transaction TRAA sends the record to system B, and waits for the response.
  3. Transaction TRBB in system B receives the record from system A.
  4. Transaction TRBB processes the record, and sends a response to system A.
  5. Transaction TRAA receives the response, and deletes the record from the temporary storage queue.

These steps are repeated as long as there are records remaining in the queue. When the queue is empty:

  1. Transaction TRAA sends a 'last record' indicator to system B.
  2. Transaction TRBB sends a response to system A.

There are several points at which you may consider taking a syncpoint. Here are the relative merits of taking a syncpoint at each of these points:

At the start of processing
Because a UOW starts at this point, a syncpoint has no effect. In fact, if TRBB tries to take a syncpoint without having first issued a command to receive data, it will be abended.
After transaction TRAA receives a response
A syncpoint at this point causes CICS to commit a record in system B before it has been deleted from system A. If either system (or the connection between them) fails before the distributed process is completed, data may be duplicated.
Immediately after the record is deleted from the temporary storage queue
Because minimum processing is needed before resources are committed, this may be a safe place to take a syncpoint if the queue is long or the records are large. However, performance may be poor because a syncpoint is taken for each record transmitted.
After transaction TRAA receives the response to the last-record indicator
If you take a syncpoint only when all records have been transmitted, an earlier failure will mean that all data will have to be retransmitted. A distributed process that syncpoints only at this stage will complete more quickly than one that syncpoints after each record is processed, provided no failure occurs. However, it will take longer to recover. If more than two systems are involved in the process, this problem is made worse.

Bear in mind that too many conversations within one distributed transaction complicates error recovery. A complex structure may sometimes be unavoidable, but usually it means that the design could be improved if some thought is given to simplifying the structure of the distributed transaction.

A UOW must be recoverable for the whole process of which it forms a part. All changes made by both partners in every conversation must be backed out if the UOW does not complete successfully. Syncpoints are not arbitrary divisions, but must reflect the functions of the application. Units of work must be designed to preserve consistent resources so that when a transaction fails, all resources are restored to their correct state.

Before terminating a sync level-2 conversation, make sure that the partner transaction is able to communicate any errors that it may have found. Not doing so may jeopardize data integrity.

[[ Contents Previous Page | Next Page Index ]]