애플리케이션 작성
본 장에서는 애플리케이션 프로그램을 작성하는 방법에 대해서 기술한다.
1. 애플리케이션 작성 과정
애플리케이션의 작성에는 애플리케이션의 설계, 프로그래밍, 디버그 및 실행의 단계로 나눌 수 있다.
각각의 단계에는 OSI에 필수로 정의되어야 하는 리소스부터 사용자가 임의로 작성하는 프로그래밍까지 포함한다.
애플리케이션 설계
애플리케이션의 설계는 다음의 과정으로 진행된다.
-
개발자는 애플리케이션이 어떠한 타입의 사용자 서버에서 구동될 것인지를 결정해야 한다.
애플리케이션의 처리를 담당하는 사용자 서버에는 MPP 사용자 서버와 BMP 사용자 서버가 있는데, 애플리케이션이 위 2개의 방식 중 어떤 방식으로 실행될 것인가를 결정해야 한다.
-
서버의 타입이 정해지면 애플리케이션과 사용자 서버와의 관계를 정해야 한다.
애플리케이션과 사용자 서버와의 관계를 정하는 방법은 시스템 리소스 정의(System Resource Definition)에서 정의할 수 있다.
다음은 시스템 정의에 대한 예제이다.
APPLCTN PSB=OIVPI001,PGMTYPE=(,,),SCHDTYP=PARALLEL TRANSACT CODE=OIVPMPP1,MSGTYPE=(SNGLSEG,RESPONSE,1),PRTY=(1,5), X MODE=SNGL APPLCTN PSB=OIVPI002,PGMTYPE=(TP,,1),SCHDTYP=PARALLEL TRANSACT CODE=OIVPMPP2,MSGTYPE=(SNGLSEG,RESPONSE,1),PRTY=(1,5), X MODE=SNGL,MAXRGN=1 APPLCTN PSB=OIVPIL05,PGMTYPE=BATCH,SCHDTYP=PARALLEL TRANSACT CODE=OIVPBMP5,MSGTYPE=(SNGLSEG,RESPONSE,1),PRTY=(1,5), X MODE=SNGL
-
애플리케이션을 설계한다. 애플리케이션은 유지보수, 확장성을 고려한 프로그램 구조, 모듈 설계가 이루어져야 한다. 애플리케이션을 설계할 때 다음 사항을 유의해야 한다.
-
DL/I 함수 호출을 효과적으로 사용해야 한다.
-
입/출력 처리 횟수를 최소화해야 한다.
-
사용 데이터베이스의 데이터 구조와 처리 옵션(검색, 추가, 삭제)에 대한 고려를 해야 한다.
-
처리 모드(대화 모드 처리, 일반 트랜잭션의 모드 등)의 설정에 대해 고려해야 한다.
-
메시지 경로에 대해 고려해야 한다.
-
프로그래밍
OSI 애플리케이션은 COBOL로 작성하며 다음 사항에 유의하면서 작성한다.
-
프로그램의 시작 조건의 설정에 유의한다.
-
DB-PCB, IO-PCB, ALT-PCB의 설정에 유의한다.
-
함수 호출 인터페이스의 설정에 유의한다.
-
Status code의 체크와 에러 처리의 설정에 유의한다.
-
데이터 처리할 때의 정합성에 유의한다. (예: 데이터 길이)
-
프로그램의 종료 조건의 설정에 유의한다. (예: 반환코드)
-
프로그램 정의에서 입/출력 데이터 크기나 SSA 크기에 관계없이 프로그래밍할 때 데이터 전송 영역은 충분한 사이즈를 확보해야 한다.
Batch 애플리케이션
Batch 애플리케이션은 OpenFrame의 유틸리티인 tjesmgr에 의해서 실행된다. Batch 애플리케이션의 작성 방법은 기본적으로 MPP 애플리케이션과 동일하다. 단지 JCL을 통해서 실행된다는 점이 다르다. tjesmgr은 JCL을 효과적으로 실행할 수 있는 유틸리티이다.
Batch 애플리케이션은 Online 업무를 위한 프로그램이 아니므로 단말과의 통신을 위한 데이터 영역을 정의할 필요는 없다. 프로그램이 데이터베이스에 연결할 수 있는 로직과 MQ(Message Queue)에서 메시지를 로드할 수 있는 로직 또는 MQ에 데이터를 다시 쌓을 수 있는 로직만 있으면 된다.
2. MPP 애플리케이션
IMS/DC Online 환경에서 메시지를 처리하는 프로그램을 MPP(Message Processing Program) 또는 MPR(Message Processing Region)이라고 한다. OSI에서는 이들을 각각 시스템 서버와 사용자 서버로 분리하여 통칭한다.
다음은 Online 환경에서 OSI 시스템과 애플리케이션의 구성을 나타내는 그림이다.
일반적으로 단말(LTERM)로부터 입력된 트랜잭션은 시스템 서버(Control Region)에 의해 분석되고 이 트랜잭션을 처리하는 MPP 애플리케이션은 OSI의 사용자 서버 중 하나인 MPP 사용자 서버에 로드되어 실행된다. 이 트랜잭션이 OSI 시스템에 전달하는 데이터 영역은 트랜잭션 코드(최대 8 문자)와 데이터 영역으로 구성되는데, 시스템 서버는 전달받은 트랜잭션 코드를 이용하여 RTSD(RunTime System Definition) 테이블로부터 클래스 정보를 취득하고, 해당 클래스를 처리하는 MPP 사용자 서버로 스케줄링하게 된다.
MPP 애플리케이션은 Get Unique(GU) Call로 단말로부터 입력된 메시지를 얻을 수 있다. 여러 개의 사용자 서버를 기동하여 다수의 MPP 애플리케이션 처리를 할 수 있으며, 데이터베이스를 동시에 접근하는 일도 가능하다. LTERM 뿐만 아니라 트랜잭션 간에도 ALT-PCB를 사용해서 MPP 애플리케이션을 시작할 수 있다.
2.1. MPP 사용자 서버 준비
MPP 사용자 서버를 기동하는 데 필요한 사항은 Tmax 환경 파일 설정, MPP 기동 JCL 파일 준비가 있다. OSI에는 OSIMPPSVR 바이너리 파일 하나로 Tmax의 target 옵션을 사용하여 서로다른 클래스 정보를 처리하는 MPP 서버를 기동시킬 수 있다.
Tmax 환경 파일 설정
OSI는 Tmax 환경에서 동작하기 때문에 사용자 서버도 Tmax 서버에 등록을 해야 정상적으로 동작한다. 서버 등록 방법은 Tmax에서 서버를 등록하는 일반적인 방법과 동일하다. Tmax 서버를 등록할 때 관련된 서비스도 같이 등록해야 한다.
################################################################################ # OpenFrame OSI Dependent Region Servers # ################################################################################ OSIMPPSVR SVGNAME = svg_node1, MIN = 1, MAX = 10, RESTART = NO ################################################################################ # OSI, example in which IMSID is IMSA # ################################################################################ IMSASCHD SVGNAME = svg_node1, MAX = 1, SVRTYPE = UCS, RESTART = NO, TARGET = osisschd IMSACMMD SVGNAME = svg_node1, MAX = 1, SVRTYPE = UCS, RESTART = NO, TARGET = osicmdsv IMSAMPP_TCL1 SVGNAME = svg_node1, MIN = 1, MAX = 10, RESTART = NO, TARGET = OSIMPPSVR IMSAMPP_TCL2 SVGNAME = svg_node1, MIN = 1, MAX = 10, RESTART = NO, TARGET = OSIMPPSVR IMSAMPP_TCL3 SVGNAME = svg_node1, MIN = 1, MAX = 10, RESTART = NO, TARGET = OSIMPPSVR IMSAMPP_TCL4 SVGNAME = svg_node1, MIN = 1, MAX = 10, RESTART = NO, TARGET = OSIMPPSVR *SERVICE ################################################################################ # OSI USER APPLICATION SERVER DEFAULT # ################################################################################ OSIMPPSVRSVC SVRNAME = OSIMPPSVR, SVCTIME=60
MPP 서버 기동 JCL
다음은 시스템 서버(Control Region) 이름이 IMSA인 경우 관리자가 생성한 사용자 서버(Dependent Region)에 해당하는 MPP 사용자 서버를 기동하는 JCL 파일이다. 클래스를 지정하지 않을 시 '000' 으로 설정 가능하며 첫 번째 클래스는 필수로 지정해야 한다. (본 예제에서 처리할 클래스는 1, 2, 3, 4이다)
//IMSAMSG JOB //STEP1 EXEC PGM=DFSRRC00, // PARM='MSG,001002003004,W00099000,,,R,,,,IMSA,,,,D2PA' //STEPLIB DD DISP=SHR,DSN=OSI.IMSA.STEPLIB //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSDBOUT DD SYSOUT=* //
2.2. MPP 프로그래밍
MPP 프로그래밍의 기본은 GU와 ISRT Call에 의해 이루어진다.
메시지를 GU 처리하는 경우는 IO-PCB를 사용해서 CBLTDLI 함수를 호출한다. 메시지가 1개 이상의 세그먼트로 구성되어 있는 경우에는 2번째 이후 세그먼트는 GN Call을 통해서 메시지를 읽어들여야 한다(SPA를 사용하는 트랜잭션의 경우에는 GU로 SPA를 읽어들이고 그 이후에 GN로 메시지를 읽는다).
GU와 GN Call의 결과는 IO-PCB의 Status code 필드에 설정된다. MPP 프로그램은 Call 처리 후 반드시 Status code를 체크해야 한다. 메시지 세그먼트를 단말로 보내거나 다른 트랜잭션으로 보내는 경우에는 데이터 영역에 메시지 세그먼트를 정해진 포맷으로 설정해서 ISRT Call로 CBLTDLI 함수를 호출한다.
다른 MPP 프로그램 또는 다른 단말에 메시지를 보낼 수 있는데 ALT-PCB를 사용해서 Destination을 지정해야 한다.
주의사항
다음은 MPP 프로그래밍의 주의사항이다.
-
트랜잭션이 입력될 때마다 스케줄되어 MPP가 동적으로 빈 사용자 서버에 로딩된다. MPP의 처리를 완료한 후, 사용하고 있던 사용자 서버는 다른 MPP 프로그램에 할당되거나 IDLE 상태로 되기 때문에 MPP 사용자 서버 내에 정보를 저장할 수 없다. 데이터의 저장이 필요한 경우에는 SPA를 사용한다.
-
MPP의 실행을 위해서 OSI가 해야 하는 사전 처리가 많기 때문에 한번 MPP가 로드되면 다수의 메시지를 처리하는 프로그램을 작성한다. 하지만 메시지의 처리를 위해서 너무 많은 시간을 소비하면 시스템을 정의할 때 지정한 우선순위에 따라서 균일화된 트랜잭션 스케줄링을 못할 수 있다. 이 경우는 시스템 정의에서 TRANSACT 매크로의 PROCLIM 지정을 활용한다.
-
MPP로 데이터베이스를 갱신하는 경우에는 데이터베이스에 대한 처리를 수행하기 때문에 주의가 필요하다. 애플리케이션을 필요 이상으로 너무 크게 해서 데이터베이스의 액세스를 독점하는 경우가 없도록 주의해야 한다.
-
균등한 스케줄링 서비스를 수행하기 위해서 1개의 트랜잭션으로 많은 시간을 필요로 하는 MPP를 작성하지 말고 여러 개의 MPP에 분할하도록 프로그래밍한다.
-
MPP는 처리 중에 Status code를 검사해서 문제가 있는 경우 더 이상의 처리를 불가능하게 만든다. 데이터베이스를 처리하는 중 데이터베이스의 백 아웃이 필요한 경우에는 반드시 이상종료(ABEND)시켜야 한다.
-
OpenFrame 환경설정 중 hidb 서브젝트, HIDB_DEFAULT 섹션의 USE_DBD_DBMS_LOCK 키의 값이 YES로 설정되어 있을 경우, 트랜잭션이 시작될 때 트랜잭션이 사용하는 DBD 명으로 Lock이 생성되고, 트랜잭션이 종료될 때 Lock이 해제된다. 자세한 사항은 "OpenFrame 환경설정 안내서"를 참조한다.
2.3. 메시지 세그먼트 포맷
다음은 수신 메시지 세그먼트, 송신 메시지 세그먼트, 프로그램 간 메시지 세그먼트에 대한 설명이다.
수신 메시지 세그먼트
COBOL 프로그램(애플리케이션)에서는 단말 혹은 다른 트랜잭션으로부터 메시지를 전달받는데 CBLTDLI 함수의 GU, GN Call을 사용하여 COBOL에 정의한 데이터 영역으로 읽어들인 데이터를 수신한다.
일반적으로 애플리케이션이 수신한 메시지 세그먼트의 포맷은 다음과 같다.
LL ZZ DATA
필드 | 설명 |
---|---|
LL |
LL 및 ZZ 필드의 길이를 포함한 메시지 세그먼트의 길이로 2bytes의 2진수이다. PL/I로 기술된 애플리케이션의 경우는 4byte이며, (실제의 길이-2)의 길이로 설정된다. (LL = DATA 길이+4) |
ZZ |
2bytes로 데이터 액세스를 위한 영역이다. 이 필드는 개발자가 설정할 필요없는 필드로 임의로 수정할 경우 에러가 발생한다. |
DATA |
단말로부터 입력된 메시지 세그먼트이다. 메시지 세그먼트는 트랜잭션 코드와 데이터 영역으로 구성된다. 단말로 보내진 데이터에는 앞 8bytes가 트랜잭션 이름이 되며, 그 이후부터가 실제 데이터가 된다. 복수의 메시지 세그먼트로 입력되는 메시지의 경우, 최초의 메시지 세그먼트의 선두 8bytes 이내에 반드시 트랜잭션 코드를 포함한다. |
송신 메시지 세그먼트
애플리케이션에서 단말, 다른 트랜잭션, 다른 단말로 메시지를 보내는 경우에는 CBLTDLI 함수의 ISRT Call을 사용하여 IO-PCB 혹은 ALT-PCB에 설정된 Destination으로 메시지를 보낸다.
송신 메시지 세그먼트의 포맷은 다음과 같다.
LL ZZ DATA
필드 | 설명 |
---|---|
LL |
LL 및 ZZ 필드의 길이를 포함한 메시지 세그먼트의 길이로 2bytes의 2진수이다. PL/I로 기술된 애플리케이션의 경우는 4bytes이다. 애플리케이션에서 반드시 이 필드를 설정해야 한다. (LL = DATA 길이 + 4) |
Z1 |
1Byte로 데이터 액세스를 위한 영역이다. 애플리케이션에서는 이 필드에 2진수로 0을 입력해야 한다. |
Z2 |
1Byte로 논리 페이징을 할 때 새로운 페이지의 시작을 MFS에게 알려야 하는 경우 X'40’을 입력한다. 이 외의 경우에는 2진수로 0을 입력해야 한다. 자세한 내용은 OpenFrame OSI "MFS 참조 안내서"를 참고한다. |
DATA |
특정 Destination(현재 단말, 다른 트랜잭션, 다른 단말)로 보내는 데이터 영역이다. 메시지 세그먼트의 길이는 Destination에 따라 다르다. 메시지는 여러 메시지 세그먼트라도 상관없다. |
프로그램 간 메시지 세그먼트
특정 프로그램으로부터 다른 프로그램으로 메시지를 보낼 수 있다. 프로그램 간 메시지를 전달하는 경우 앞에서 설명한 송신 메시지 세그먼트와 방법이 동일하다.
다음은 프로그램 간 전달하는 메시지 세그먼트의 포맷이다.
LL ZZ DATA
필드 | 설명 |
---|---|
LL, ZZ |
송신 메시지 세그먼트의 포맷과 같다. |
DATA |
상대 프로그램에 메시지를 보내는 데이터이다. |
주의사항
다음은 프로그램 간 전달하는 메시지 세그먼트를 사용할 때 주의해야 하는 사항이다. 애플리케이션에서 사용하는 ALT-PCB 는 PSB에 미리 정의되어 있어야 하며, 애플리케이션에서 사용할 PCB들(LINKAGE SECTION 및 ENTRY 구문)은 PSB에 정의된 PCB들의 순서대로 정의되어 있어야 한다.
-
애플리케이션 AP1으로부터 다른 애플리케이션 AP2에게 메시지를 보내는 경우 ALT-PCB를 사용하며 ALT-PCB의 Destination을 보내려는 AP2의 이름으로 설정한 다음 CHNG, ISRT, PURG 순서로 DL/I 함수를 사용한다.
-
AP2에서 메시지를 수신할 때 IO-PCB를 지정하여 해당 메시지를 수신할 수 있다. IO-PCB에는 AP1의 ALT-PCB의 내용이 설정되어야 정상적으로 데이터(데이터 구조 정합성)를 받을 수 있다.
-
AP2에서 수신 메시지를 처리한 후, 다시 메시지를 AP1에 송신하는 경우에는 AP1의 ALT-PCB를 지정한다. 이 경우 AP1이 AP2로부터 메시지를 받아들여 처리를 하고, 메시지를 단말에 출력하는 경우에는 IO-PCB를 지정해 메시지를 송신한다. AP2가 메시지를 수신할 수 있는 것은 MPP나 BMP의 경우이다.
3. BMP 애플리케이션
MPP와 달리 사용자는 데이터베이스 액세스 기능 외에 데이터 관리를 사용하고, OSI에서 사용자 데이터셋을 액세스할 수 있다. 데이터베이스나 메시지를 처리하는 프로그램 방식은 MPP와 같다. MPP 프로그래밍과 차이점은 MQ에 적재되어 있는 데이터를 실시간으로 처리하는 것이 아니고 사용자가 원하는 때에 JCL을 통해 BMP 애플리케이션을 기동하여 처리한다는 점이다.
예를 들어 MPP 애플리케이션을 통해 처리된 결과물을 ALT-PCB(Alternative Program PCB)를 사용해 BMP 애플리케이션으로 보내면 OSI는 MQ 테이블에 그 결과를 적재하고 대기하다가 사용자가 JCL로 해당 BMP 애플리케이션을 실행시킬 때 MQ 테이블에 적재되어있는 모든 메시지를 Destination인 해당 BMP 애플리케이션으로 보낸다.
다음은 BMP 프로그램을 기동시키는 JCL의 예제이다.
<OSIBMP.jcl>
//OSIBMPT JOB CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1) //TSTEP1 EXEC PGM=DFSRRC00, // PARM=(BMP,OIVPIL04,,OIVPBMP4,,,,,,,,,,IMSA,) //SYSOUT DD SYSOUT=*
다음은 앞의 JCL을 실행하는 tjesmgr 유틸리티를 실행하는 예제이다.
$ tjesmgr run OSIBMP.jcl > Command : [run OSIBMP.jcl] Node name : NODE1 /home/oframe/OpenFrame/volume_default/SYS1.JCLLIB/OSIBMP.jcl is submitted as OSIBMPT(JOB00001). $ tjesmgr ps > Command : [ps] JOBNAME JOBID CLASS STATUS RC NODE JCL ------------------------------------------------------------------------------ OSIBMPT JOB00001 A Done R00000 NODE1 OSIBMP.jcl