1CICS技术文档第八章CICS队列设施在前面第5章我们已经讨论了CICS对VSAM文件和数据库这样一些外部数据进行访问的方法。接下来我们将在本章讨论CICS中另外一种外部数据的内容,即两种CICS队列设施的支持。队列是为保存一些短期数据的需要而设计的。例如如我们可能需要临时存储打印记录、工作数据或屏幕映像页面,有时候CICS应用的程序间可能需要传递超过32K的数据,此时COMMAREA就无法完成,通常我们用队列来过渡进行程序间大量数据的传递。CICS提供为外部数据提供的两种队列设施:瞬时数据队列和临时存储队列。8.1CICS队列设施简介CICS提供一种工具来存储那些实际上当作瞬时或临时的数据、这些数据由一个或多个在线事务创建或收集,随后被同一个事务或另一个事务使用或传送到一个批处理程序中而被使用。这些数据以一个队列元素的形式存储。CICS中有两类队列:瞬时数据队列(TDQ)和临时存储队列(TSQ)。瞬时数据队列TDQ允许写到队列中的数据被另外一个事务程序使用或脱机处理,它必须预先定义在DCT(DestinationControlTable)中。瞬时数据队列又分为两种:瞬时数据队列和外部瞬时数据队列。内部TDQ的所有队列的元素(数据项)存储在一个特定的VSAM数据集中,这个数据集由CICS进行管理,它只能被CICS访问,它在CICS启动的JCL或PROC中用DD语句指定,一旦CICS启动后它就被CICS独占,其化批处理程序是不能直接访问的;而外部TDQ的每一个队列是一个单独的顺序数据集,由用户或管理员用CICS的资源定义工具,如CEDA,定义到CSD文件中去。它允许在不出现冲突的情况下同时被CICS程序和批程序读取。临时存储队列TSQ不需要预先定义,队列中的记录可被顺序或直接读写,它分为主存TSQ和辅存TSQ。主存TSQ的元素保存在CICS内存中,CICS重启后这些数据一般不保存,辅存TSQ的元素保存在外部存储区中,即文件中,CICS重启后这些数据一般予以保留。8.2瞬时数据队列CICS的瞬时数据队列提供了一种应用广泛的临时存储服务。为了后续的内部或外部的处理,数据可以被临时存储在瞬时数据队列中。用户在应用程序中指定的数据,可以被发送到预先定义好的内部(Intrapartition)瞬时数据队列或外部(Extrapartion)瞬时数据队列,反之亦然。队列在CICS中又称为目的地(Destination)。2目的地如果与分配给CICS区域的设施关联,就是内部(IntraPartition)瞬时数据队列;如果数据是要导出到CICS区域外的目的地的,则是外部的(ExtraPartition)瞬时数据队列。这些目的地必须在CICS运行时由系统程序员将其作为资源定义在目的地控制表(DCT)中。CICS对瞬时数据队列提供了3个应用编程接口:(1)写数据到一个瞬时数据队列(WRITEQTD命令);(2)从一个瞬时数据队列读数据(READQTD命令);(3)删除一个内部瞬时数据队列(DELETEQTD命令)。如果TD这个关键字被省略的话,这几个命令默认是对临时储存数据队列进行操作。瞬时数据队列像事务一样由一个被称为DestinationID的四个字符ID来标识。DestinationID和其化的瞬时数据队列的特性由系统程序员在目的地控制表(DCT)中定义。其队列项的长度可变。我们可以用图8.1来表示瞬时数据总体情况。图8.1内部瞬时数据队列8.2.1内部瞬时数据队列内部(Intrapartition)瞬时数据是指为作为独立任务运行的一个或多个程序所用的在直接访问的存储设备(DASD)上的数据、被导入/导出内部的存储地点的数据被称为内部瞬时数据,它必须由可变长的记录组成。内部瞬时数据队列的目的地可以与一个终端或一个输出数据集相连,内部瞬时数据队列可能最终被传送到发送请求的终端或从输出数据集检索获得。内部瞬时数据的特性:(1)所有的队列使用同一个VSAM(ESDS)数据集,也就是说某个CICS区域使用一3个ESDS格式的VSAM文件来存储该区域里的所有的内部瞬时数据队列的元素。(2)记录是可变长度格式。(3)每个队列的记录必须按照一个接一个地顺序写人。(4)每个队列的记录被顺序检索。一旦一个记录被读出,它就不能再被任何任务所访问,也就是说对内部瞬时数据队列的读是破坏性读取。(5)可用内部瞬时数据队列进行自动进行任务初始化(AutoTaskInitiate,ATI)。(6)不可修改记录。需要注意的是,虽然多个CICS任务可同时向同一个瞬时数据队列写数据,但同一时刻只允许一个任务从该瞬时数据队列读数据。对瞬时数据队列的读写过程如图8.2所示。图8.2访问瞬时数据队列在图8.2中,当执行READQ/WRITEQTD命令时,通过过TDP访DCT,来对内部瞬时数据集VSAM(ESDS)数据集进行顺序操作。内部(Intrapartition)瞬时数据队列典型的用途有;(l)信息交换;(2)广播;(3)数据库访问;(4)把输出发送到几个终端;(5)数据排队;(6)数据收集。8.2.3外部瞬时数据外部(Extrapartion)目的地是存放任一种顺序设备(DAS儿磁带,打印机,等等)上的队列(数据集),这些数据集是被在CICS区域内(或外)的程序访问的。通常来说,顺序外部瞬时数据队列用来存储和获得在CICS区域外的数据。例如,一个任务可能从远程终4端读数据、编辑数据和把结果写到一个其化CICS区域顺序处理的数据集上。诸如运行记录、统计信息和事务错误信息等数据都可以写人外部瞬时数据队列。通常来说,由CICS创建的外部瞬时数据队列是为随后的对非CICS程序的批输入准备的。这些数据也可以被送往如同打印机一样的输出设备。导人到一外部队列或从外部队列导出的数据被当成外部(Extrapartion)数据访问,这些数据由顺序的记录组成。而这些记录可以是定长或变长的、成块的或不成块的.外部(Extrapartion)队列的记录格式必须在DCT中被系统程序员定义。作为应用程序开发人员一般不允许删除一个外部瞬时数据队列,否则,将会产生一个非法请求(INVREQ)的错误。外部瞬时数据的特点如下:(1)外部瞬时数据是CICS对顺序访问方法的支持。(2)每一个队列是一个物理顺序数据集(QSAM)。(3)每一个队列在DCT中能被定义为输人队列或输出队列;但一个队列不能同时定义为既是输人又是输出的队列。(4)由于每个外部队列是一个文件,用户可以选择这个文件什么时候应该被打开,例如在CICS系统初始化时、或之后用主控终端事务CEMT来手动打开一样,这一点和VSAM文件的处理很类似。(5)队列中的记录可以是定长或变长格式,成块或不成块的。(6)通过批程序可访问队列记录。8.2.4瞬时数据队列的访间向瞬时数据队列写入数据WRITEQ命令既可用于内部数据队列又可用于外部瞬时数据队列的写操作。命令基本格式为:EXECCICSWRITEQTDQUEUE(name)FROM(data-area)[LENGTH(data-value)]其功能为将data-area指定的COBOL变量的内容作为一条记录写入名字为name的TDQ队列中。从瞬时数据队列读入数据READQ命令既可用于内部数据队列又可用于外部瞬时数据队列的读取。命令基本格式为:EXECCICSREADQTDQUEUE(name)INTO(data-area)[LENGTH(data-area)]其功能为从名字为name的TDQ中读取记录放到data-area指定的COBOL变量中。TDQ队列的删除5没有专门对于队列中项记录进行删除的命令,只能对整个队列即所有项的删除的操作。前面讲过对TDQ队列的读是一种破坏性读取,当某条记录被读后,相当于该记录也被删除了。并且DELETEQ命令只适用于内部瞬时队列的删除。它用于删除所有与该队列名相关的记录。所有在内部VSAM数据集上与该队列相关的内容会被删除,而相应的存储空间会被释放。很显然DELETEQ是一种物理删除,因此需谨慎考虑好再删除。命令基本格式为:EXECCICSDELETEQTDQUEUE(name)其功能为删除名为name的整个内部TD。异常条件处理在对队列的检索过程中,要考虑出现如下异常;QZERO,LENGERRQZERO:目的地文件为空或到了瞬时数据队列尾。通常,正在读取瞬时数据队列的任务会读出所有的记录,直到队列空为止。可预见的特定处理NOSPACE,NOTOPEN,QBUSYNOSPACE:在内部瞬时数据集上已无空间。NOTOPEN:外部目的地文件已关闭,应该使用控制终端事务CEMT来打开。QBUSY:试图访问一个正在被另一个任务写或被删除的内部瞬时数据集上的记录。对于大多数异常条件的缺省动作是任务异常终止,而对QBUSY,则是任务被挂起,即对发出READQTD命令的任务的缺省动作是一直等待到该队列不再被用于输出为止。错误IOERR,QIDERRIOERR:一个对瞬时数据队列IO错误,如磁盘损坏。QIDERR:队列名错误,一般是由于命令中用的队列没有在CICS中定义和安装。对于大多数异常条件,如果这些异常条件不被处理,CICS异常终止其任务;而对少数异常条件,CICS挂起任务直到期望的命令能成功执行完。8.2.5访问瞬时数据队列的实例例8.1写瞬时数据队列的例子.WORKING-STORAGESECTION.01WRKFLDS.05TD-RECLPICS9(4)COMP.05TD-ERR-CODEPICS9(8)COMP.05F-ERR-CODEPICS9(8)COMP.0oF-NUMBPICX(6)VALUEZERO.01TD-REC.02TDDATEPICX(8).02TD-NUMBPICX(6).02TD-AMOUNTPICX(8).0lFILEREC602STATPICX.02NUMBPICX(6).02AMOUNTPICX(8).PROCEDUREDIVISION.EXECCICSSTARTBRFILE('FILEA')RIDFLD(F-NUMB)GTEQEND-EXEC.PERFORMUNTILF-ERR-CODEEQUALDFHRESP(ENDFILE)EXECCICSREADNEXTFILE('FILEA')INTO(FILEREC)RIDFLD(F-NUMB)RESP(F-ERR-CODE)END-EXEC.IFF-ERR-CODEEQUALDFHRESP(NORMAL)MOVEEIBDATETOTD-DATEMOVENUMBTOTD-NUMBMOVEAMOUNTTOTD-AMOUNTMOVE22TOTD-RECLEXECCICSWRITEQTDQUEUE('LSTC')FROM(TD-REC)LENGTH(TD-RECL)RESP(TD-ERR-CODE)END-EXEC.IFTD-ERRCODENOTEQUALDFHRESP(NORMAL)PERFORMERROR-ROUTINEENDIFELSEIFF-ERR-CODENOTEQUALDFHRESP(ENDFILE)PERFORMERROR-ROUTINEEND-IFEND-IFEND-PERFORMEXECCICSENDBRFILE('FILEA')ENDEXEC.EXECCICSRETURNEND-EXEC.说明:EXECCICSSTARTBRFILE('FITEA')RIDFLD(F-NUMB)GTEQEND-EXEC.例子中的GTEQ为大于等于之意。程序中斜体部分为将长度为TD-RECL的记录TD-REC写向队列LSTC中,并将返回码7写入TD-ERR-CODE中。程序部分的IFF-ERR-CODENOTEQUALDFHRESP(ENDFILE)PERFORMERRORROUTINEEND-IF表示如果F-ERR-CODE不为NORMAL,即所读文件时出现异常,则执行ERRORROUTINE程序。最后程序循环执行读,一直读到ENDFILE。例8.2瞬时数据输人例子,获取瞬时数据队列里的所有