Efficiently transferring large data between TXSeries and CICS TS programs

Using channels and containers

Typically you transfer data between TXSeries® and CICS® TS programs using a communication area (COMMAREA), which has a maximum limit of 32K bytes. With the implementation of channels and containers in TXSeries 7.1, you can exchange data of unlimited size between these programs. This article gives an overview of channels and containers, including their creation, usage, advantages, best practices, migrating COMMAREA-based application to use channels and some customer scenarios. A sample application shows how to pass data from a TXSeries to a CICS TS program using channels and containers.

Share:

Arpana K. Vishweshwarappa (arpana.kv@in.ibm.com ), System Software Engineer, IBM

author photoArpana is a software engineer in IBM, India Software Labs. She is currently working in the TXSeries development team and has expertise in designing and developing applications for middleware such as TXSeries.



02 December 2009

Introduction

Traditionally, you would transfer data between TXSeries and CICS Transaction Server (hereafter referred as CICS TS) programs using a communication area (COMMAREA), which only can send a maximum of 32K bytes of data. If an application had to send more than 32K of data, then the application would handle it by chunking the large data into 32K blocks and doing multiple DPLs. Thus the application is responsible for the logic of chunking large data and then grouping it after receiving. Figure 1 shows how data is passed between programs using a COMMAREA.

Figure 1. Data transfer between programs using a COMMAREA
Diagram showing data transfer between programs using a COMMAREA with a 32KB limit

Now with the availability of channels and containers, you can pass data of unlimited size between TXSeries programs, CICS TS programs and from a TXSeries program to a CICS TS program. Channels and containers also provide a structured way of sending the data.


Channels and containers

Wherever I mention data transfer between programs, it can be between TXSeries programs, between CICS TS programs, or between TXSeries and CICS TS programs.

A container is a block of data designed for passing information between programs. Containers are grouped together in sets called channels. There is no limit on the number of containers that you can add to a channel, and the size of each container is limited only by the amount of storage available. A channel is a standard mechanism for exchanging data between programs. Figure 2 shows how data is passed between programs using channels and containers.

Figure 2. Data transfer between programs using channels and containers
Diagram showing data transfer between programs using channels and containers

APIs related to channels and containers

TXSeries provides EXEC CICS APIs to create, delete, reference, access and manipulate a container and associate it with a channel:

  • To create the container and the channel in which it is to be placed, use the PUT CONTAINER API.
  • To pass a channel between programs, use the LINK, XCTL, START and RETURN APIs with the channel parameter specified.
  • A called application can know when a channel is passed to it by using the ASSIGN CHANNEL API. If a channel is passed, it returns the channel name else returns blanks.
  • To retrieve the data from a container, use the GETCONTAINER API.
  • To transfer data from a container to another container in the same channel or different channel, use the MOVE CONTAINER API.
  • To delete a container explicitly in the program, use the DELETE CONTAINER API. A channel will be deleted automatically when it goes out of scope, that is, when no program can access it.

PRG1

Listing 1. Creating and using containers in a C program
/* Creating a container cont1 and placing it in channel chan1 */
EXEC CICS PUT CONTAINER(“cont1”)  
	CHANNEL(“chan1”)
	FROM(instr)
	FLENGTH(len);

/* Passing the channel chan1 to  program PRG2 */
EXEC CICS LINK 
	PROGRAM(“PRG2”)
	SYSID(“ISC”)
	CHANNEL(“chan1”);

PRG2

/* Getting the channel name */
EXEC CICS ASSIGN 
CHANNEL(chan_name);

/* Retrieving the data from cont1 */
EXEC CICS GET 
CONTAINER(“cont1”) CHANNEL(chan_name) 
INTO(outstr) 
FLENGTH(len);

/*  Moving cont1 from chan1 as cont2 in chan2 */
EXEC CICS MOVE CONTAINER(“cont1”) 
AS(“cont2”) CHANNEL(chan_name)
TOCHANNEL(“chan2”);

/* Delete cont2 from chan2 */
EXEC CICS DELETE
CONTAINER(“cont2”)
CHANNEL(“chan2”);

Terminology

  • Current channel: A program’s current channel is the channel (if any) with which it was invoked. Although the program can create other channels, the current channel for a particular invocation of a specific program never changes. The current channel is set by the calling program or transaction by issuing a LINK, XCTL, START and pseudo-conversational RETURN with the channel parameter. To discover a program’s current channel, use the ASSIGN CHANNEL API.
  • Channel scope: A program can only access channels it has created, or the current channel with which it was invoked. Figure 3 clearly shows the scope of a channel and the current channel associated with the program.

    Figure 3. Example demonstrating current channel and scope of a channel
    Diagram showing scope of channel EMP_INFO is Program A, Program B and Program C, and scope of channel MGR_INFO is Program D and Program E

Scenarios showing how to use channels

The following examples show how you might employ a channel in your application program flow.

  • One channel/one program: The simplest technique is to use a channel and its collection of containers to invoke a program as shown in Figure 4. You specify the channel name on the EXEC CICS LINK command, and the target application program always knows exactly which channel it will be passed.
    Figure 4. Passing a channel between two programs
    Diagram showing passing the channel EMP_INFO from Program 1 to Program 2
  • One channel/multiple programs: Another technique is for the first program to create a channel and some containers. This program could then link to another program passing the channel along. Subsequent programs could use the same channel, with the same or different containers, for their exchange of data. In this example we maintain only one copy of the data. Figure 5 shows passing a channel across multiple programs.
    Figure 5. Passing a channel across multiple programs
    Diagram showing passing the channel EMP_INFO from Program 1 to Program 2 and then to Program 3
  • Multiple channels/one program: In this scenario a program links to multiple programs, passing them different channels as shown in Figure 6. You can see that Program A links to two programs, B and C. Each program is passed a different channel describing the different interfaces.
    Figure 6. Passing multiple channels in a single program using multiple DPLs
    Diagram showing passing the channel EMP_INFO from Program A to Program 2 and Program 3
  • Multiple channels/multiple programs: In this scenario, multiple programs pass different channels to the same program. In Figure 7, you can see Program1 and Program2 send different channels to Program3. Program3 is a server program that can process requests from a number of different clients.
    Figure 7. Passing multiple channels in multiple programs
    Diagram showing passing the channels EMP_VER1 from Program 1 and EMP_VER1 from Program 2 to Program 3

Browsing containers in a channel

As previously mentioned, a channel can have any number of containers. You can browse them using the BROWSE APIs. Each GETNEXT API returns the container name present in the channel being browsed. Listing 2 shows APIs used to browse the containers in a channel.

Listing 2. Browsing containers in a channel
EXEC CICS STARTBROWSE CONTAINER 
BROWSETOKEN(&token) CHANNEL(chan_name);

EXEC CICS GETNEXT CONTAINER(cont_name) BROWSETOKEN(token);

EXEC CICS ENDBROWSE CONTAINER BROWSETOKEN(token);

Data conversion

Apart from providing the ability to send large data, channels and containers simplify data conversion by making it part of the application program. There are two types of containers: CHAR and BIT. You can only convert data on CHAR containers using PUT and GET APIs passing the CCSID (Coded Character Set Identifier) parameter. This will be mostly useful when passing data between systems with different character encoding. For example, the default character encoding used in TXSeries (distributed platforms) is ASCII, and the one used in CICS TS (z/OS) is EBCDIC. So when you pass data from TXSeries to CICS TS, it should be converted from ASCII to EBCDIC as shown in Listing 3 and Listing 4.

Listing 3. Data conversion using channels and containers - TXSeries Region
PUT CONTAINER(“CONT1”) FROM(str) FLENGTH(len) FROMCCSID(819)
Listing 4. Data conversion using channels and containers - CICS TS Region
GET CONTAINER(“CONT1”) INTO(str) FLENGTH(len) INTOCCSID(037)

In Listing 3, FROMCCSID is specified as 819 (819 is the CCSID for ASCII). This value means that the data we are putting into CONT1 is in ASCII format. In Listing 4, INTOCCSID is specified as 037 (037 is the CCSID for EBCDIC). This value means that the data retrieved will be converted to EBCDIC format.'

Best practices

Because channels and containers deal with passing large data, you must consider a few design options to improve the overall performance of the application. The following tips describe how to use channels and containers to improve performance:

  • When using channels with DPL, only the changed and new containers are returned to the calling program when a DPL is complete. Take for example where PRG1 passes channel CHAN to PRG2 (See Figure 8). Then all the containers in channel CHAN are passed from PRG1 to PRG2. But only modified or newly created containers in channel CHAN are returned back to PRG1. So keeping this in mind, it’s always good to create the different containers for INPUT, OUTPUT and ERROR so that only the INPUT container passes from PRG1 to PRG2. On returning, only the OUTPUT and ERROR containers (if any error has happened) are returned, because the INPUT container is unchanged and need not be returned.
    Figure 8. Using separate containers for input, output and error
    Diagram showing passing the DETAILS channel from Program A to Program B, with separate containers for INPUT, OUTPUT and ERROR
  • Use separate containers for read-only data versus read-write data. In addition, in some programs some structures are optional. Create separate containers for them to improve the transmission efficiency and to pass data in a more structured way between programs, which increases readability.
  • Whenever an application is expecting a particular container (for example, ERROR) instead of browsing all the containers in a channel to get that particular container ERROR, it can use the GET container (“ERROR”) API and handle the response values appropriately. If the ERROR container is present in the channel, then the response value will be normal; otherwise the response value will give CONTAINERERR.
  • Use separate containers for different data types, such as, binary data and character data. These containers will improve your ability to easily move between different code pages. CCSID conversion happens in the GET API if the CCSID of the container does not match the CCSID specified in the INTOCCSID parameter of the GET container. If an application needs to execute the GET API for the same container multiple times at different points, and if that needs CCSID conversion, then you shouldn’t call the GET API many times, but instead the application should maintain a local copy of the container and use it for any other further references.

Migrating a COMMAREA-based application to use channels

The following examples show how to convert an application program that is using a COMMAREA to one using a channel and container.

Programs using LINK

As shown in Figure 9, you can see Program1 links to Program2 passing COMMAREA. And in Program2, COMMAREA is retrieved using ADDRESS COMMAREA API.Figure 10 shows the same application using channels and containers to pass data. Program1 creates the container and channel using PUT CONTAINER API and passes it to Program2 using LINK API. In Program2, container is retrieved using GET CONTAINER API. And Program2 sends back the data by creating a new/modifying container in the passed channel.

Figure 9. Application using COMMAREA
Diagram showing passing structure COMMAREA from Program 1 to Program 2
Figure 10. Migrated application using channels and containers
Diagram showing passing a channel and a container from Program 1 to Program 2

Programs using START

Figure 11 shows Transaction1 passing data to Transaction2 via START TRANSID API using FROM option. The same application is changed to pass data via START TRANSID API using CHANNEL option as shown in Figure 12.

Figure 11. Application using COMMAREA
Diagram showing passing the structure COMMAREA from Transaction 1 to Transaction 2
Figure 12. Migrated application using channels and containers
Diagram showing passing a channel and a container from Transaction 1 to Transaction 2

Customer scenarios

In a typical customer scenario, usually a client invokes a transaction in a TXSeries region. A client such as CICS Transaction Gateway can pass a channel to TXSeries via the IPIC protocol. Then TXSeries can handle the channel based on application logic, and can pass it on to a CICS TS region as described in the article. The following scenarios show where channels and containers can be used:

  1. Consider TXSeries deployed in a healthcare domain that requires large images like scanned images, X-rays etc, be passed between the programs. Assume a scenario as shown in Figure 13, where a client collates a large amount of data in the form of a patient’s medical history, passes on to a server program which provides, by return, a small amount of data which is the patient’s current diagnosis. Channels and containers are best suited in these type of applications, because we are sending a huge amount of data, and there is a performance improvement as server sends only the ‘current_diagnosis’ container back to client since ‘patient_details’ and ‘medical_history’ containers remain unchanged.
    Figure 13. Using channels and containers in healthcare domain
    Diagram showing passing a DETAILS channel from Program 1 to Program 2, with Patient_details, Medical_history, and Current _diagnosis
  2. Another example where channels and containers can be used is online shopping where a user will select a particular item from the catalog and send it to the server using channels and containers (see Figure 14). The server sends all details about that item such as its price, features, image, etc., to the user.

    Figure 14. Using channels and containers in online shopping
    Diagram showing passing a DETAILS channel from Program A to Program B, with Item_id and Item_details, Medical_history, and Current _diagnosis

Basically channels and containers can be used in all scenarios where a client needs to send or receive a large amount of data (> 32KB).


Sample Application

The sample application, provided as a download with this article, contains a C program running under a TXSeries region, which creates a channel and passes a channel to a C program running under a CICS TS region. This application is developed and tested using TXSeries 7.1 and CICS TS 3.2.


Conclusion

Channels and containers overcomes the limit of passing only 32K data between programs. Using COMMAREA remains the basic method for passing data, but you can use channels and containers when you need to transfer a large amount of data between programs. Minimal changes are required to migrate a COMMAREA-based application to use channels and containers. Additionally, with channels and containers, you pass data in a more structured way, and it makes the data conversion simpler and easier.


Download

DescriptionNameSize
Sample codeprogs.zip2KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=451284
ArticleTitle=Efficiently transferring large data between TXSeries and CICS TS programs
publish-date=12022009