内容


在 TXSeries 和 CICS TS 程序之间高效地传输大型数据

使用管道和容器

Comments

简介

在以前,您可能使用传统的通信区域(COMMAREA)在 TXSeries 和 CICS Transaction Server(此后称为 CICS TS)程序之间传输数据,COMMAREA 支持的最大数据为 32K 字节。如果应用程序发送的数据大于 32K,那么应用程序必须将大型数据分割成 32K 的数据块,并进行多次 DPL。因此应用程序不仅要负责分割数据,还需要在接收数据之后将它们组合起来。图 1 显示如何使用 COMMAREA 在应用程序之间传输数据。

图 1. 使用 COMMAREA 在应用程序之间传输数据
使用 COMMAREA 在应用程序之间传输的最大数据为 32K
使用 COMMAREA 在应用程序之间传输的最大数据为 32K

现在,通过使用管道和容器,您可以在 TXSeries 应用程序之间或从 TXSeries 程序到 CICS TS 程序传输任意大小的数据。管道和容器还为数据的发送提供一种结构化的方式。

管道和容器

容器 是用于在程序之间传递信息的数据块。容器被分成组包含在管道 中。您可以向一个管道添加任意数量的容器,并且每个容器的大小仅受到可用储存空间的限制。管道是在程序之间交换数据的标准机制。图 2 显示了如何使用管道和容器在程序之间传递数据。

图 2. 使用管道和容器在程序之间传递数据
使用管道和容器在程序之间传递数据
使用管道和容器在程序之间传递数据

与管道和容器相关的 API

TXSeries 提供用于创建、删除、引用和操作容器并将容器与管道关联起来的 EXEC CICS API:

  • 要创建容器和包含容器的管道,请使用 PUT CONTAINER API。
  • 要在程序之间传递管道,请将 LINK, XCTL, STARTRETURN API 与指定的管道参数一起使用。
  • 被调用的应用程序能够通过 ASSIGN CHANNEL 知道管道将在何时被传递给它。如果管道已传递,它将返回管道名,否则返回空格。
  • 要从容器获取数据,使用 GETCONTAINER API。
  • 要在相同的管道中将数据从一个容器传输到另一个容器或将数据传输到另一个管道中的容器,使用 MOVE CONTAINER API。
  • 要显式地删除程序中的容器,使用 DELETE CONTAINER API。当管道超出了作用域范围(即程序不能访问它)时,将被自动删除。

PRG1

清单 1. 在 C 程序中创建和使用容器
/* 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”)
	SYSI(“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”);

术语

  • 当前管道:程序的当前管道 是用于调用应用程序的管道。尽管程序可以创建其他管道,但是用于调用特定应用程序的管道是永远不变的。通过发出带有管道参数的 LINK、XCTL、START 和伪会话 RETURN,当前管道由调用程序或事务实现。要查看程序的当前管道,使用 ASSIGN CHANNEL API。
  • 管道作用域:程序只能访问它创建的管道或调用它的当前管道。图 3 清楚地展示了管道的作用域和与程序相关联的当前管道。
    图 3. 演示当前管道和管道作用域的例子
    管道 EMP_INFO 的作用域为 Program A、Program B 和 Program C,MGR_INFO 的作用域为 Program D 和 Program E
    管道 EMP_INFO 的作用域为 Program A、Program B 和 Program C,MGR_INFO 的作用域为 Program D 和 Program E

演示如何使用管道的场景

下面的例子展示如何在应用程序流中使用管道。

  • 一个管道/一个程序:最简单的技术就是使用一个管道和它的容器集来调用程序,如图 4 所示。您使用 EXEC CICS LINK 命令来指定管道名,并且目标应用程序通常能够准确地知道通过哪个管道传递它。
    图 4. 在两个程序之间传递管道
    将管道 EMP_INFO 从 Program 1 传递到 Program 2
    将管道 EMP_INFO 从 Program 1 传递到 Program 2
  • 一个管道/多个程序:另一种技术是第一个程序先创建一个管道和一些容器。然后该程序可以链接到另一个程序并传递管道。后续的程序可以使用这个管道(使用相同或不同的容器)来交换数据。在这个例子中,我们仅维护数据的一个副本。图 5 显示了在多个程序之间传递一个管道。
    图 5. 在多个程序之间传递一个管道
    将管道 EMP_INFO 从 Program 1 传递到 Program 2,然后再传递到 Program 3
    将管道 EMP_INFO 从 Program 1 传递到 Program 2,然后再传递到 Program 3
  • 多个管道/一个程序:在这个场景中,一个程序链接到多个程序,并传递不同的管道,如图 6 所示。您可以看到,程序 A 链接到程序 B 和 C。每个程序都传递一个描述不同接口的管道。
    图 6. 使用多个 DPL 在一个程序中传递多个管道
    将管道 EMP_INFO 从 Program A 传递到 Program 2 和  Program 3
    将管道 EMP_INFO 从 Program A 传递到 Program 2 和 Program 3
  • 多个管道/多个程序:在这个场景中,多个程序将不同的管道传递到相同的程序。在图 7 中,您可以看到 Program1 和 Program2 将不同的管道发送到 Program3。Program3 是一个服务器程序,可以处理来自不同客户端的请求。
    图 7. 在多个程序之间传递多个管道
    将管道 EMP_VER1 从 Program 1 以及将管道 EMP_VER1 从 Program 2 传递到 Program 3
    将管道 EMP_VER1 从 Program 1 以及将管道 EMP_VER1 从 Program 2 传递到 Program 3

浏览管道中的容器

如前所述,管道可以包含任意数量的容器。您可以使用 BROWSE API 浏览它们。每个 GETNEXT API 都返回在所浏览的管道中显示的容器名。清单 2 显示用于浏览管道中的容器的 API。

清单 2. 浏览管道中的容器
EXEC CICS STARTBROWSE CONTAINER 
BROWSETOKEN(&token) CHANNEL(chan_name);

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

EXEC CICS ENDBROWSE CONTAINER BROWSETOKEN(token);

数据转换

除了提供发送大型数据的能力之外,管道和容器还通过将数据转换包含到程序中实现了简化。有两种类型的容器:CHAR 和 BIT。您仅能够使用传递 CCSID (Coded Character Set Identifier) 参数的 PUT 和 GET API 转换 CHAR 容器上的数据。当使用不同的字符编码在系统之间传递数据时,这尤其有用。例如,在 TXSeries(分布式平台)中使用的默认字符编码为 ASCII,在 CICS TS (z/OS) 中使用的字符编码为 EBCDIC。因此,当您将数据从 TXSeries 传递到 CICS TS 时,必须将数据从 ASCII 转换成 EBCDIC,如清单 3 和清单 4 所示。

清单 3. 使用管道和容器转换数据 - TXSeries Region
PUT CONTAINER(“CONT1”) FROM(str) FLENGTH(len) FROMCCSID(819)
清单 4. 使用管道和容器转换数据 - CICS TS Region
GET CONTAINER(“CONT1”) INTO(str) FLENGTH(len) INTOCCSID(037)

在清单 3 中,FROMCCSID 被指定为 819819 是针对 ASCII 的 CCSID)。这个值意味着我们放入到 CONT1 的数据的格式为 ASCII。在清单 4 中,INTOCCSID 被指定为 037037 是针对 CCSID 的 CCSID)。这个值意味着我们接收的数据将被转换成 EBCDIC 格式。

最佳实践

因为管道和容器处理大型数据的传递,因此您必须考虑一些改进应用程序的总体性能的选项。以下技巧描述了如何使用管道和容器来改善性能:

  • 将 DPL 与管道一起使用时,在 DPL 完成后,只将已更改的和新的容器返回到调用程序。以 PRG1 将管道 CHAN 传递到 PRG2 为例(见图 8)。然后,管道 CHAN 中的所有容器都从 PRG1 传递到 PRG2。但仅将在管道 CHAN 中修改的或新创建的容器返回到 PRG1。因此,为 INPUT、OUTPUT 和 ERROR 创建不同的容器是一项最佳实践,这样能够只将 INPUT 容器从 PRG1 传递到 PRG2。在返回时,仅返回 OUTPUT 和 ERROR 容器(如果发生错误的话),因为 INPUT 没有改变,所以不需要返回它。
    图 8. 为 INPUT、OUTPUT 和 ERROR 使用独立的容器
    将 DETAILS 管道从 Program A 传递到 Program B,针对 INPUT、OUTPUT 和 ERROR 的容器是独立的
    将 DETAILS 管道从 Program A 传递到 Program B,针对 INPUT、OUTPUT 和 ERROR 的容器是独立的
  • 对只读而不是读写数据使用独立的容器。此外,在某些程序中有一部分结构是可选的。为这些可选的结构创建独立的容器以改善传输效率,以及在程序之间以更加结构化的方式传递数据,从而增加可靠性。
  • 当应用程序正在获取特定的容器(例如,ERROR)时,它没有浏览管道中的所有容器以获取该容器,而是使用 GET 容器 (“ERROR”) API 并正确地处理响应值。如果 ERROR 容器出现在管道中,那么响应值就是正常的;否则,响应值就为 CONTAINERERR。
  • 对不同的数据类型使用独立的容器,比如二进制数据和字符型数据。这些容器能够提高在不同的代码页之间移动的能力。如果容器的 CCSID 不匹配在 GET 容器中的 INTOCCSID 参数中指定的 CCSID,转换仅发生在 GET API 中。如果应用程序需要为相同的容器多次执行 GET API,并且需要用到 CCSID 转换,那么您不需要多次调用 GET API,因为应用程序将保存该容器的一个本地副本并用于其它引用。

迁移基于 COMMAREA 的应用程序以使用管道

下面的例子显示如何将使用 COMMAREA 的应用程序转换成使用管道和容器的应用程序。

使用 LINK 的程序

如图 9 所示,您可以看到 Program1 链接到传递 COMMAREA 的 Program2。在 Program2 中,使用 ADDRESS COMMAREA API 来获取 COMMAREA。图 10 显示使用管道和容器来传递数据的相同应用程序。Program1 使用 PUT CONTAINER API 来创建容器和管道,并使用 LINK API 将其传递到 Program2。在 Program2 中,使用 GET CONTAINER API 来获取容器。Program2 通过在已传递的管道中创建新的或修改现有的容器来发送回数据。

图 9. 使用 COMMAREA 的应用程序
将结构 COMMAREA 从 Program 1 传递到 Program 2
将结构 COMMAREA 从 Program 1 传递到 Program 2
图 10. 迁移应用程序以使用管道和容器
将管道和容器从 Program 1 传递到 Program 2
将管道和容器从 Program 1 传递到 Program 2

使用 START 的应用程序

图 11 显示了 Transaction1 使用 FROM 选项通过 START TRANSID API 将数据传递到 Transaction2。对该应用程序进行更改,以使用 CHANNEL 选项通过 START TRANSID API 传递数据,如图 12 所示。

图 11. 使用 COMMAREA 的应用程序
将结构 COMMAREA 从 Transaction 1 传递到 Transaction 2
将结构 COMMAREA 从 Transaction 1 传递到 Transaction 2
图 12. 迁移应用程序以使用管道和容器
将管道和容器从 Transaction 1 传递到 Transaction 2
将管道和容器从 Transaction 1 传递到 Transaction 2

客户场景

在典型的客户场景中,客户端通常在 TXSeries 区域中调用事务。客户端(比如 CICS Transaction Gateway)能够通过 IPIC 协议将管道传递到 TXSeries。然后,TXSeries 能够根据应用程序逻辑处理管道,并像本文中所描述的一样将它传递到 CICS TS 区域。下面的场景显示可以使用管道和容器的场景:

  1. 考虑部署在医疗领域的 TXSeries,它需要在程序之间传递大型图片(比如扫描图片、X 光图片等)。假设有一个类似于图 13 的场景,其中客户端将大量数据整理成患者的病历,并将其传递到一个服务器程序中,该程序提供患者的当前诊断数据(很少)。管道和容器非常适合用于这样的应用程序中,因为我们需要发送大量数据,并且当服务器仅将 ‘current_diagnosis’ 容器发送回给客户端时会改善性能,因为 ‘patient_details’‘medical_history’ 容器保持不变。
    图 13. 在医疗领域使用管道和容器
    显示将管道 DETAILS 从 Program 1 传递到 Program 2,并且包含 Patient_details、Medical_history 和 Current _diagnosis
    显示将管道 DETAILS 从 Program 1 传递到 Program 2,并且包含 Patient_details、Medical_history 和 Current _diagnosis
  2. 可以使用管道和容器的另一个例子是在线购物,其中用户从目录中选择一件商品并使用管道和容器将其发送到服务器(见图 14)。服务器将与该商品相关的所有细节,比如价格、特征和图片等,发送给用户。
    图 14. 在在线购物中使用管道和容器
    显示将管道 DETAILS 从 Program A 传递到 Program B,包含 Item_id、Item_details、Medical_history 和 Current _diagnosis
    显示将管道 DETAILS 从 Program A 传递到 Program B,包含 Item_id、Item_details、Medical_history 和 Current _diagnosis

一般而言,管道和容器可用于所有客户端需要接收或发送大量数据(大于 32KB)的场景。

样例应用程序

样例应用程序(可从本文末尾 下载)包含一个在 TXSeries 区域下运行的 C 程序,它创建一个管道并将一个管道传递到在 CICS TS 区域下运行的 C 程序。这个应用程序使用 TXSeries 7.1 和 CICS TS 3.2 进行开发和测试。

结束语

管道和容器克服了在程序之间传输的数据最大为 32K 的限制。使用 COMMAREA 保留了传送数据的基本方法,但当您需要在程序之间传输大型数据时,可以使用管道和容器。仅需少量更改就可以将基于 COMMAREA 的应用程序修改为使用管道和容器。此外,通过管道和容器,您可以以更加结构化的方式传递数据,并使得数据的转换更加简单容易。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=470212
ArticleTitle=在 TXSeries 和 CICS TS 程序之间高效地传输大型数据
publish-date=03012010