OpenTP1 Version 7　分散トランザクション処理機能　OpenTP1 プログラム作成の手引

手引書

3000-3-D51-90

前書き

対象製品

マニュアル「OpenTP1 解説」を参照してください。

輸出時の注意

本製品を輸出される場合には、外国為替及び外国貿易法の規制並びに米国輸出管理規則など外国の輸出関連法規をご確認の上、必要な手続きをお取りください。

なお、不明な場合は、弊社担当営業にお問い合わせください。

商標類

HITACHI，JP1，OpenTP1，OSAS，uCosminexus，XMAPは，株式会社 日立製作所の商標または登録商標です。

Oracle(R)，Java及びMySQLは，Oracle，その子会社及び関連会社の米国及びその他の国における登録商標です。

UNIXは，The Open Groupの登録商標です。

Windowsは，マイクロソフト 企業グループの商標です。

その他記載の会社名，製品名などは，それぞれの会社の商標もしくは登録商標です。

本書には，X/Openの許諾に基づき X/Open CAE Specification System Interfaces and Headers，Issue4，（C202 ISBN 1-872630-47-2）Copyright (C) July 1992，X/Open Company Limitedの内容が含まれています；

なお，その一部は IEEE Std 1003.1-1990，(C) 1990 Institute of Electrical and Electronics Engineers, Inc.及び IEEE std 1003.2/D12，(C) 1992 Institute of Electrical and Electronics Engineers, Inc.を基にしています。

事前に著作権所有者の許諾を得ずに，本書の該当部分を複製，複写及び転記することは禁じられています。

本書には，X/Openの許諾に基づき X/Open Preliminary Specification Distributed Transaction Processing : The TxRPC Specification（P305 ISBN 1-85912-000-8）Copyright (C) July 1993，X/Open Company Limitedの内容が含まれています；

事前に著作権所有者の許諾を得ずに，本書の該当部分を複製，複写及び転記することは禁じられています。

本書には，Open Software Foundation, Inc.が著作権を有する内容が含まれています。

This document and the software described herein are furnished under a license, and may be used and copied only in accordance with the terms of such license and with the inclusion of the above copyright notice. Title to and ownership of the document and software remain with OSF or its licensors.

発行

2023年7月　3000-3-D51-90

著作権

All Rights Reserved. Copyright (C) 2006, 2023, Hitachi, Ltd.

変更内容

変更内容（3000-3-D51-90） uCosminexus TP1/Server Base 07-60，uCosminexus TP1/Server Base(64) 07-60

追加・変更内容

変更個所

追加，変更個所はない。

−

単なる誤字・脱字などはお断りなく訂正しました。

変更内容（3000-3-D51-80） uCosminexus TP1/Server Base 07-57，uCosminexus TP1/Server Base(64) 07-57，uCosminexus TP1/Server Base 07-56，uCosminexus TP1/Server Base(64) 07-56，uCosminexus TP1/Server Base 07-54，uCosminexus TP1/Server Base(64) 07-54，uCosminexus TP1/Server Base 07-53，uCosminexus TP1/Server Base(64) 07-53

追加・変更内容

マニュアル訂正の内容を反映した。

TAMサービスの関数とフラグに設定した値について説明を追加した。

変更内容（3000-3-D51-73） uCosminexus TP1/Server Base 07-54，uCosminexus TP1/Server Base(64) 07-54，uCosminexus TP1/Server Base 07-53，uCosminexus TP1/Server Base(64) 07-53

追加・変更内容

エントリポイント名に関する説明を追加した。

セクタ長に関する説明を追加した。

環境変数の設定例を追加した。

変更内容（3000-3-D51-72） uCosminexus TP1/Server Base 07-53，uCosminexus TP1/Server Base(64) 07-53

追加・変更内容

コーディング時の注意事項に記載しているマルチスレッドに関する説明を変更した。

マルチOpenTP1のコマンドを振り分けるサンプルに関する説明を変更した。

変更内容（3000-3-D51-71） uCosminexus TP1/Server Base 07-51，uCosminexus TP1/Server Base(64) 07-51，uCosminexus TP1/Message Control 07-51，uCosminexus TP1/Message Control(64) 07-51，uCosminexus TP1/NET/Library 07-51，uCosminexus TP1/NET/Library(64) 07-51

追加・変更内容

マニュアル訂正の内容を反映した。

変更内容（3000-3-D51-70） uCosminexus TP1/Server Base 07-51，uCosminexus TP1/Server Base(64) 07-51，uCosminexus TP1/Message Control 07-51，uCosminexus TP1/Message Control(64) 07-51，uCosminexus TP1/NET/Library 07-51，uCosminexus TP1/NET/Library(64) 07-51

追加・変更内容

ERREVT2が通知された原因に関する説明を追加した。

次の時間監視の設定時間と所要時間の誤差に関する説明を追加した。

同期型のメッセージ処理の時間監視

アプリケーションプログラムの起動のタイマ起動

非トランザクション属性のMHPの時間監視

ユーザタイマ監視機能による時間監視

makeコマンドを実行するタイミングについての説明を追加した。

変更内容（3000-3-D51-60） uCosminexus TP1/Server Base 07-50，uCosminexus TP1/Server Base(64) 07-50，uCosminexus TP1/Message Control 07-50，uCosminexus TP1/Message Control(64) 07-50，uCosminexus TP1/NET/Library 07-50，uCosminexus TP1/NET/Library(64) 07-50

追加・変更内容

非常駐プロセスを終了させる場合の，スケジュールキューに滞留しているサービス要求の数について，説明を変更した。

dc_mcf_execap関数でアプリケーションを起動する場合に関連づけるシステム定義に関する説明を追加した。

閉塞されている論理端末のメッセージが未処理送信メッセージ滞留時間の対象とならないことを追加した。

排他なし参照使用時の注意事項を追加した。

変更内容（3000-3-D51-50） uCosminexus TP1/Server Base 07-06，uCosminexus TP1/Server Base(64) 07-06

追加・変更内容

一時的にプロセス数が増加するタイミング，および非常駐プロセスでも同一プロセスで続けてサービス要求を処理する場合について，説明を追加した。

性能検証用トレースの情報をCSV形式で出力し，トレース解析できるようにした。

ノード構成の変更（ノードの追加や削除）に自動的に対応する機能（ノード自動追加機能）を追加した。

再送できるメッセージの条件と，システムサービス定義との関連について説明を追加した。

uCosminexus TP1/Server Base 07-05，uCosminexus TP1/Server Base(64) 07-05，uCosminexus TP1/Message Control 07-05，uCosminexus TP1/Message Control(64) 07-05

追加・変更内容

一つのサービス要求ごとに実行するプロセスを起動し直せるようにした（非常駐UAPプロセスのリフレッシュ機能）。

一つのリソースマネジャを複数の制御単位に分け，接続するユーザ名称などを変更してリソースマネジャに接続できるようにした（リソースマネジャ接続先選択機能）。

uCosminexus TP1/Message Control 07-00，uCosminexus TP1/Message Control(64) 07-00

追加・変更内容

リモートMCFサービスに関連する記述を削除した。

変更内容（3000-3-D51-40） uCosminexus TP1/Server Base 07-04，uCosminexus TP1/Server Base(64) 07-04，uCosminexus TP1/Message Control 07-05，uCosminexus TP1/Message Control(64) 07-05，uCosminexus TP1/NET/Library 07-05，uCosminexus TP1/NET/Library(64) 07-05

追加・変更内容

サービス関数動的ローディング機能で使用する，UAP共用ライブラリのサーチパスをオンライン中に変更できるようにした。

OpenTP1の起動コマンドがリターンした直後にMCFの運用コマンドを実行する場合，mcftlscomコマンドでMCF通信サービスの開始を待ち合わせられるようにした。

mcftlsleコマンドで，最大未送信メッセージ数を表示できるようにした。

これに伴い，dc_mcf_tlsle関数との機能差異の説明を追加した。

非応答型のMHPからの問い合わせ応答をできるようにした。

異常終了したMHPを，自動的に再スケジュールできるようにした。

TX_関数の使用方法で，ユーザサービス定義との関連について説明を変更した。

変更内容（3000-3-D51-30） uCosminexus TP1/Server Base 07-03，uCosminexus TP1/Server Base(64) 07-03，uCosminexus TP1/Message Control 07-03，uCosminexus TP1/Message Control(64) 07-03，uCosminexus TP1/NET/Library 07-04，uCosminexus TP1/NET/Library(64) 07-04

追加・変更内容

OpenTP1のUAPをコーディングする場合の注意事項を追加した。

通知する先のCUPの説明に，dc_clt_chained_accept_notification関数を追加した。

グローバルドメインについての説明を追加した。

OpenTP1の標準出力，標準エラー出力をリダイレクトするprcteeプロセスを停止・再開始できるようにした。

これに伴い，次のコマンドを追加した。

prctctrl

アプリケーションに関するタイマ起動要求の状態を表示できるようにした。

これに伴い，次のコマンドを追加した。

mcfalstap

ユーザタイマ監視の状態を表示できるようにした。

これに伴い，次のコマンドを追加した。

mcftlsutm

UAP異常終了通知イベント，および未処理送信メッセージ廃棄通知イベントの，MCFイベントが通知された原因の説明を変更した。

OpenTP1の正常終了コマンドを実行すると，タイマ起動要求メッセージはすぐに破棄され，ERREVTAが通知される旨の説明を追加した。

サンプルディレクトリの，tools/ディレクトリの説明を変更した。

uCosminexus TP1/Message Control 07-02，uCosminexus TP1/NET/Library 07-03

追加・変更内容

MHPでサービス関数動的ローディング機能を使用できるようにした。

MCF通信サービスまたはアプリケーション起動サービスの状態を，ライブラリ関数で表示できるようにした。

これに伴い，次の関数を追加した。

dc_mcf_tlscom

CBLDCMCF('TLSCOM ')

コネクションの状態表示，確立，および解放を，ライブラリ関数でできるようにした。

これに伴い，次の関数を追加した。

dc_mcf_tactcn

dc_mcf_tdctcn

dc_mcf_tlscn

CBLDCMCF('TACTCN ')

CBLDCMCF('TDCTCN ')

CBLDCMCF('TLSCN ')

サーバ型コネクションの確立要求の受付開始・終了を，ライブラリ関数でできるようにした。

これに伴い，次の関数を追加した。

dc_mcf_tofln

dc_mcf_tonln

CBLDCMCF('TOFLN ')

CBLDCMCF('TONLN ')

コネクションの確立要求の受付状態を，ライブラリ関数で表示できるようにした。

これに伴い，次の関数を追加した。

dc_mcf_tlsln

CBLDCMCF('TLSLN ')

アプリケーションに関するタイマ起動要求を，ライブラリ関数で削除できるようにした。

これに伴い，次の関数を追加した。

dc_mcf_adltap

CBLDCMCF('ADLTAP ')

論理端末の状態表示，閉塞，閉塞解除，および出力キューの削除を，ライブラリ関数でできるようにした。

これに伴い，次の関数を追加した。

dc_mcf_tactle

dc_mcf_tdctle

dc_mcf_tdlqle

dc_mcf_tlsle

CBLDCMCF('TACTLE ')

CBLDCMCF('TDCTLE ')

CBLDCMCF('TDLQLE ')

CBLDCMCF('TLSLE ')

相手システムとのメッセージ送受信に関するネットワークの状態を表示できるようにした。

これに伴い，次のコマンドを追加した。

mcftlsln

運用操作で使用する関数と運用コマンドの機能差異についての説明を追加した。

通信プロトコル対応製品と運用操作で使用できる関数の対応についての説明を追加した。

uCosminexus TP1/Message Control 07-01，uCosminexus TP1/NET/Library 07-01

追加・変更内容

サーバ型コネクションの確立要求の受付開始・終了を，手動でできるようにした。

これに伴い，次のコマンドを追加した。

mcftofln

mcftonln

リアルタイム統計情報の取得項目として，MCFの情報も取得できるようにした。

変更内容（3000-3-D51-20） uCosminexus TP1/Server Base 07-02，uCosminexus TP1/Message Control 07-01，uCosminexus TP1/NET/Library 07-01

追加・変更内容

監査ログを出力する機能を追加した。

これに伴い，UAPで監査ログを取得する実装方法を追加した。

サービス関数を動的にローディングできる機能を追加した。

リモートAPI機能に関する説明を変更した。

はじめに

このマニュアルは，次に示すOpenTP1のプログラムプロダクトで使うアプリケーションプログラムの作成方法について説明しています。

分散トランザクション処理機能　TP1/Server Base

分散アプリケーションサーバ　TP1/LiNK

このマニュアルでは，アプリケーションプログラムの英略称を「ユーザが作成するアプリケーションプログラム」の意味で，UAP（User Application Program）と表記します。

本文中に記載されている製品のうち，このマニュアルの対象製品ではない製品については，OpenTP1 Version 7対応製品の発行時期をご確認ください。

次に示す製品，および各製品に示したバージョン以降で，ソケット受信型サーバに関する機能はすべて廃止しました。そのため，ユーザサービス定義とユーザサービスデフォルト定義のreceive_fromオペランドでsocketは使用できません。

P-1M64-2141 uCosminexus TP1/Server Base：07-53-01以降

P-1M64-1121 uCosminexus TP1/Server Base(64)：07-53-01以降

P-1J64-2171 uCosminexus TP1/Server Base：07-51-02以降

P-1J64-1171 uCosminexus TP1/Server Base(64)：07-51-01以降

P-8164-2111 uCosminexus TP1/Server Base：07-57以降

P-8264-2111 uCosminexus TP1/Server Base(64)：07-57以降

P-2464-2294 uCosminexus TP1/Server Base：07-60以降

P-2964-2234 uCosminexus TP1/Server Base(64)：07-60以降

なお，該当する機能を使用した場合の動作は保証できないため，ご注意ください。

対象読者

TP1/Server Base，またはTP1/LiNKで使うアプリケーションプログラムを作成するプログラマの方々を対象としています。

オペレーティングシステム，オンラインシステム，使うマシンの操作，およびアプリケーションプログラムのコーディングに使う高級言語（C言語，C++言語，またはCOBOL言語）の文法の知識があることを前提としています。

このマニュアルの記述は，マニュアル「OpenTP1 解説」，またはマニュアル「TP1/LiNK 使用の手引」の知識があることを前提としていますので，あらかじめお読みいただくことをお勧めします。

文法の記号

このマニュアルで使用する各種記号を説明します。

(1)文法記述記号

指定する値の説明で使用する記号の一覧を示します。

文法記述記号

意味

【　　】

隅付き括弧

C言語の関数名に対応するCOBOL言語の関数名をこの記号で囲んで表記しています。それ以降は，C言語の関数名に統一して説明します。

X/Open発行のドキュメントの内容から引用した記述について

X/Open発行の「X/Open CAE Specification Distributed Transaction Processing : The XATMI Specification」の内容から引用した部分

上記ドキュメントに示された仕様の解釈を，OpenTP1での使用方法として，このマニュアルの次に示す部分に記載しました。

5章　X/Openに準拠したアプリケーションプログラミングインタフェース

5.1　XATMIインタフェース（クライアント／サーバ形態の通信）

X/Open発行の「X/Open CAE Specification Distributed Transaction Processing : The TX（Transaction Demarcation） Specification」の内容から引用した部分

上記ドキュメントに示された仕様の解釈を，OpenTP1での使用方法として，このマニュアルの次に示す部分に記載しました。

5章　X/Openに準拠したアプリケーションプログラミングインタフェース

5.2　TXインタフェース（トランザクション制御）

X/Open発行の「X/Open Preliminary Specification Distributed Transaction Processing : The TxRPC Specification」の内容から引用した部分

上記ドキュメントに示された仕様の解釈を，OpenTP1での使用方法として，このマニュアルの次に示す部分に記載しました。

6章　X/Openに準拠したアプリケーション間通信（TxRPC）

謝　辞

COBOL言語仕様は，CODASYL（the Conference on Data Systems Languages：データシステムズ言語協議会）によって，開発された。OpenTP1のアプリケーションプログラムのインタフェース仕様のうち，データ操作言語（DML　Data Manipulation Language）の仕様は，CODASYL　COBOL（1981）の通信節，RECEIVE文，SEND文，COMMIT文，及びROLLBACK文を参考にし，それに日立製作所独自の解釈と仕様を追加して開発した。原開発者に対し謝意を表すとともに，CODASYLの要求に従って以下の謝辞を掲げる。なお，この文章は，COBOLの原仕様書「CODASYL COBOL JOURNAL OF DEVELOPMENT 1984」の謝辞の一部を再掲するものである。

いかなる組織であっても，COBOLの原仕様書とその仕様の全体又は一部分を複製すること，マニュアルその他の資料のための土台として原仕様書のアイデアを利用することは自由である。ただし，その場合には，その刊行物のまえがきの一部として，次の謝辞を掲載しなければならない。書評などに短い文章を引用するときは，"COBOL"という名称を示せば謝辞全体を掲載する必要はない。

COBOLは産業界の言語であり，特定の団体や組織の所有物ではない。

CODASYL　COBOL委員会又は仕様変更の提案者は，このプログラミングシステムと言語の正確さや機能について，いかなる保証も与えない。さらに，それに関連する責任も負わない。

次に示す著作権表示付資料の著作者及び著作権者

FLOW-MATIC（Sperry Rand Corporationの商標），Programming for the Univac

（R）I and II，Data Automation Systems， Sperry Rand Corporation　著作権表示

1958年，1959年；

IBM Commercial Translator Form No.F 28-8013，IBM著作権表示1959年;

FACT，DSI 27A5260-2760，Minneapolis-Honeywell，著作権表示1960年

は，これら全体又は一部分をCOBOLの原仕様書中に利用することを許可した。この許可は，COBOL原仕様書をプログラミングマニュアルや類似の刊行物に複製したり，利用したりする場合にまで拡張される。

KB（キロバイト）などの単位表記について

1KB（キロバイト），1MB（メガバイト），1GB（ギガバイト），1TB（テラバイト）はそれぞれ1,024バイト，1,024²バイト，1,024³バイト，1,024⁴バイトです。

その他の前提条件

このマニュアルをお読みになる際のその他の前提情報については，マニュアル「OpenTP1 解説」を参照してください。

1　OpenTP1のアプリケーションプログラム

OpenTP1のアプリケーションプログラムの概要について説明します。

この章では，各機能をC言語の関数名で説明します。C言語の関数名に対応するCOBOL言語のAPIは，関数を最初に説明する個所に【 】で囲んで表記します。それ以降は，C言語の関数名に統一して説明します。

1.1　ユーザアプリケーションプログラムと業務形態の関係

OpenTP1※のアプリケーションプログラム（UAP　User Application Program）は，ネットワーク（LAN，またはWAN）でつながれているメインフレーム，ワークステーション（WS），パーソナルコンピュータ（PC），および分散機と通信する，オンライントランザクション処理を実現するために作成します。

OpenTP1のUAPでできる通信形態は，次の三つです。

クライアント／サーバ形態のUAP

メッセージ送受信形態のUAP

メッセージキューイング機能を使った形態のUAP

注※

このマニュアルでは，分散トランザクション処理機能TP1/Server Baseと分散アプリケーションサーバTP1/LiNKを総称して，以降OpenTP1と表記します。

OpenTP1とUAPのネットワーク内の位置を次の図に示します。

図1‒1　OpenTP1とUAPのネットワーク内の位置

1.1.1　クライアント／サーバ形態のアプリケーションプログラム

クライアント／サーバ形態のUAPでは，ほかのUAPの処理を呼び出して業務処理を実行できます。呼び出して利用できるプログラムの単位をサービス，サービスを提供するプロセスをサーバといいます。UAPのサーバをユーザサーバといいます。

クライアント／サーバ形態の通信では，サービスを要求するUAP（クライアントUAP）とサービスを提供するUAP（サーバUAP）で一つの業務になります。サーバUAPのサービスは，複数のクライアントUAPで共用できます。

サービスを要求するときは，リモートプロシジャコール（RPC）を使います。RPCでは，サーバUAPに論理的に付けた名称（サービス名）でサービスを要求できます。このときクライアントUAPでは，サーバUAPがネットワーク上のどのノードにあるかを意識する必要はありません。

OpenTP1では，クライアント／サーバ形態の通信プロトコルにTCP/IPとOSI TPを使えます。どちらを使う場合でも，UAPでノード間の通信プロトコルを意識する必要はありません。

ノードについて

このマニュアルで意味する「ノード」とは，ネットワークにつながれた，OpenTP1が稼働する一つの計算機（マシン）のことです。ただし，マルチOpenTP1の場合は，複数のOpenTP1から構成される一つのノードになります。

クライアント／サーバ形態のUAPの概要を次の図に示します。

図1‒2　クライアント／サーバ形態のUAPの概要

1.1.2　メッセージ送受信形態のアプリケーションプログラム

メッセージ送受信形態のUAPでは，OSIに準拠したプロトコル（OSAS/UA，OSI TP），TCP/IP，および 従来型のネットワークで接続されたホストと分散機間で，メッセージの送受信による通信ができます。主に，通信管理プログラムを介した広域ネットワーク（WAN）にある他システムとの通信で使います。

メッセージ送受信をするUAPとクライアント／サーバ形態のRPCを使うUAPでは，コーディングスタイルが異なります。クライアント／サーバ形態の処理で使うUAPとは別に，メッセージ送受信専用のUAPとして作成します。

メッセージ送受信形態のUAPを使うノードには，OpenTP1のメッセージ送受信機能（TP1/Message Control，TP1/NET/Library）と通信プロトコル対応製品（TP1/NET/***）が必要です。このマニュアルでは，OpenTP1のメッセージ送受信機能（TP1/Message Control，TP1/NET/Library）と通信プロトコル対応製品を総称して，以降MCF（Message Control Facility）またはMCFサービスと表記します。

メッセージ送受信形態のUAPの概要を次の図に示します。

図1‒3　メッセージ送受信形態のUAPの概要

1.1.3　メッセージキューイング機能を使った形態のアプリケーションプログラム

メッセージキューイング機能とは，データを格納するキュー（メッセージキュー）に情報を登録したり，情報を取り出したりして通信する形態です。相手システムのアプリケーションプログラムが稼働していなくても，データを送信したり受信したりできるので，電子メールのように通信できます。

メッセージキューイング機能を使うときは，UAPからメッセージキューインタフェース（MQI）というAPIを使って操作します。

メッセージキューイング機能を使うOpenTP1のノードには，TP1/Message Queueが必要です。メッセージキューイング機能の使い方については，マニュアル「TP1/Message Queue 使用の手引」を参照してください。

メッセージキューイング機能を使ったUAPの概要を次の図に示します。

図1‒4　メッセージキューイング機能を使ったUAPの概要

1.1.4　アプリケーションプログラムの負荷分散

OpenTP1では，UAPを複数のプロセスで稼働させることで，効率良く業務を実行できます。ノード内では，一つのUAPの処理を複数のプロセスで実行させて，サーバシステムの効率を上げています。この機能をマルチサーバといいます。また，同じ名称のUAPを複数のマシンに存在させて，サービス要求をどのノードでも処理できるようにもできます。この機能をノード間負荷バランス機能といいます。UAPと実行するプロセスの関係については，「1.3.6　ユーザサーバの負荷分散とスケジュール」を参照してください。

1.1.5　アプリケーションプログラムのトランザクション処理

UAPの処理は，業務処理ごとの単位に区切って，それぞれの処理の結果を有効にするか無効にするかを明確に分ける必要があります。処理が有効であるか無効であるかどちらかに必ず決定させる単位をトランザクションといいます。OpenTP1のUAPでは，このようなトランザクションの処理ができます。

トランザクションの業務処理ごとの区切りを同期点といいます。トランザクションの処理が同期点に達した時点で，トランザクションの処理が正常に終了したか（有効）異常が起こったか（無効）を決定します。処理が正常に終了したとする同期点取得をコミットといいます。同期点まで正常に終了できなかったトランザクションの処理は，OpenTP1でそれまでの処理を取り消して，その処理がなかったように回復します。このような同期点処理をロールバック（部分回復）といいます。

(1)　クライアント／サーバ形態のUAPでのトランザクション処理

OpenTP1では，RPCを使ったクライアント／サーバ形態のUAPの処理をトランザクションとして処理できます。異なるノードにわたって，多くのサービスを続けて要求している処理でも，一つのトランザクションの処理にできます。

クライアント／サーバ形態のUAPでは，トランザクションの開始と，同期点取得を示す関数を呼び出せます。トランザクションの開始を宣言したUAPから複数のサービスをネストさせても，一つのトランザクションとして処理できます。

このようにOpenTP1では，従来のデータコミュニケーションでのトランザクション処理の信頼性を，クライアント／サーバ形態のUAPで実現できます。

(2)　メッセージ送受信形態のトランザクション処理

メッセージを処理するUAPの処理は，開始から終了まで，トランザクションにできます。この場合の同期点処理はOpenTP1で自動的に制御しています。

メッセージを処理するUAPでメッセージを受け取ったあとでは，クライアント／サーバ形態のUAPで使うトランザクション制御の関数は使えません。

1.2　アプリケーションプログラムの種類

OpenTP1のUAPには，次に示す種類があります。

クライアント／サーバ形態の通信で使うUAP

サービス利用プログラム（SUP　Service Using Program）

クライアント専用のUAPです。SUPは，OpenTP1の基本機能（TP1/Server Base，またはTP1/LiNK）が前提となります。

サービス提供プログラム（SPP　Service Providing Program）

クライアントUAPからの要求に対して，サービスを提供するUAP（サーバUAP）です。SPPは，OpenTP1の基本機能（TP1/Server Base，またはTP1/LiNK）が前提となります。

メッセージ送受信形態の通信で使うUAP

メッセージ処理プログラム（MHP　Message Handling Program）

通信回線を経由して送られたメッセージを受信して処理するUAPです。MHPの処理からSPPのサービスも要求できます。MHPは，OpenTP1の基本機能（TP1/Server Base）とメッセージ送受信機能（TP1/Message Control）が前提となります。

ユーザファイルの初期化をするUAP

オフラインの業務をするUAP

ユーザ任意の処理をするUAPです。オフラインの業務をするUAPで使えるOpenTP1のライブラリ関数は，DAMファイルを初期作成したり，バッチ環境でアクセスしたりする機能だけです。

OpenTP1クライアント機能（TP1/Client）で使うUAP

クライアントユーザプログラム（CUP　Client User Program）

クライアント専用のUAPです。WS，またはPCからTP1/Clientのライブラリ関数を使って，SPPのサービスを要求するプログラムを総称してCUPといいます。CUPは，OpenTP1クライアント機能（TP1/Client）が前提となります。

CUPについては，マニュアル「OpenTP1 クライアント使用の手引 TP1/Client/W，TP1/Client/P編」を参照してください。

なお，TP1/Client/Jを使用すると，SPPのサービスを要求するJavaアプレット，Javaアプリケーション，およびJavaサーブレットを作成できます。

詳細については，マニュアル「OpenTP1 クライアント使用の手引 TP1/Client/J編」を参照してください。

クライアント／サーバ形態のUAP（SUP，SPP）の概要を図1-5に，メッセージ送受信形態のUAP（MHP）の概要を図1-6に示します。

図1‒5　UAPの役割と位置の概要（クライアント／サーバの形態）

図1‒6　UAPの役割と位置の概要（メッセージ送受信の形態）

1.2.1　サービスを利用するUAP（SUP）

クライアント専用のUAPを，サービス利用プログラム（SUP）といいます。SUPは，サーバUAP（SPP）にサービスを要求して，クライアント／サーバ形態の通信を開始する役割のUAPです。

SUPでできる通信は，SPPにサービスを要求するだけです。ほかのUAPにサービスとして提供するための関数は作成できません。

SUPの概要を次の図に示します。

図1‒7　SUPの概要

(1)　SUPの開始

SUPを実行する場合，OpenTP1の開始と一緒に開始する方法と，OpenTP1の開始後に任意に開始する方法の2とおりがあります。OpenTP1の開始と一緒に開始すると，OpenTP1の開始と同時にUAPの業務を開始できます。作成したSUPの業務内容に応じて，開始する時期を選べます。

(a)　OpenTP1の開始と一緒に開始する場合

OpenTP1を開始する前に，OpenTP1と一緒に開始する指定をしておきます。指定方法を次に示します。

TP1/Server Baseの場合

ユーザサービス構成定義のdcsvstart定義コマンドに，開始するSUPのユーザサーバ名を指定します。

TP1/LiNKの場合

ユーザサーバ環境を設定するときに，開始するSUPが自動起動するように設定します。

(b)　OpenTP1の開始後に任意に開始する場合

OpenTP1の開始後にSUPを開始する場合は，dcsvstartコマンドの引数にSUPのユーザサーバ名を指定して実行します。

(2)　SUPの稼働時

SUPのプロセスは，一つの常駐プロセスとして確保しておきます。

オンライン中にSUPのプロセスで障害が起こった場合は，自動的に別プロセスで開始できます。別プロセスに自動的に開始させる場合，TP1/Server Baseのときは，ユーザサービス定義のauto_restartオペランドにYを指定してください。TP1/LiNKのときは，自動的に開始するように設定されています。

OpenTP1で自動的に開始できない場合は，dcsvstartコマンドで開始させてください。

(3)　SUPの終了

SUPの終了はOpenTP1で制御しません。業務終了後にSUPを正常終了させる場合は，SUP自身で終了するように作成してください。SUPの処理からトランザクションを開始しているときは，関数でトランザクションをコミット（同期点を取得）してから終了させてください。処理がうまくいかなかったためSUPを異常終了させたい場合は，exit()またはabort()を使って，SUP自身で終了するように作成してください。

SUPは，dcsvstopコマンドで正常終了させることはできません。ただし，SUPを強制停止させたい場合に限り，dcsvstop -fコマンドで終了できます。

SUPのプロセスを，killコマンドで終了させないでください。

(4)　SUPの処理の概要

SUPでは，UAPの開始（dc_rpc_open関数【CBLDCRPC('OPEN ')】）を呼び出したあとに，サーバの起動完了をOpenTP1に連絡するために，ユーザサーバの開始処理完了の報告（dc_adm_complete関数【CBLDCADM('COMPLETE')】）を必ず呼び出してください。

SUPの処理の概要を次の図に示します。

図1‒8　SUPの処理の概要（C言語の例）

1.2.2　サービスを提供するUAP（SPP）

要求されたサービスを処理するUAPを，サービス提供プログラム（SPP）といいます。SPPはOpenTP1が稼働している間，クライアントUAPから要求されたサービスを処理します。クライアントUAPからは関数呼び出しと同様の方法で，SPPのサービスを要求します。SPPがどのノードにあるかは，クライアントUAPで意識する必要はありません。

SPPは，サービスを要求されてから業務を開始します。サービスを要求されない間は，要求されるのを待っている状態となります。

SPPでは，OpenTP1のノードにあるユーザファイルへアクセスして，サーバの業務をします。OpenTP1専用のファイルへライブラリ関数でアクセスしたり，ORACLEなどのDBMSへSQL文でアクセスしたりできます。

SPPからさらに別のSPPへサービスを要求して，業務処理をネストさせることもできます。

SPPの概要を次の図に示します。

図1‒9　SPPの概要

(1)　SPPの構成

各種クライアントUAPの要求に対応するサービスを複数作成して，SPPとして一つの実行形式ファイルにまとめます。一つ一つのサービスを，C言語の場合はサービス関数（COBOL言語の場合はサービスプログラム）といいます。SPPとして一つの実行形式ファイルにするために，複数のサービスをメイン関数（COBOL言語の場合はメインプログラム）でまとめます。そして，一つのメイン関数と複数のサービス関数から構成されるSPPの実行形式ファイルを，サービスグループとしてOpenTP1に定義します。

サービス関数動的ローディング機能は，複数のサービスを UAP共用ライブラリ化※して使うため，複数のサービスをメイン関数にまとめる作業は不要です。

注※

UAP共用ライブラリ化とは，UAPのソースファイルを翻訳（コンパイル）して作成したUAPオブジェクトファイルを結合（リンケージ）して，共用ライブラリとしてまとめることです。

SPPの構成を，スタブを使う場合とサービス関数動的ローディング機能を使う場合に分けて，それぞれ以降の図に示します。

図1‒10　SPPの構成（スタブを使う場合）

図1‒11　SPPの構成（サービス関数動的ローディング機能を使う場合）

(2)　SPPの開始

SPPを実行する場合，OpenTP1の開始と一緒に開始する方法と，OpenTP1の開始後に任意に開始する方法の2とおりがあります。OpenTP1の開始と一緒に開始すると，OpenTP1の開始と同時に，SPPの業務を開始できます。SPPの業務内容に応じて，開始する時期を選べます。

(a)　OpenTP1の開始と一緒に開始する場合

OpenTP1を開始する前に，OpenTP1と一緒に開始する指定をしておきます。指定方法を次に示します。

TP1/Server Baseの場合

ユーザサービス構成定義のdcsvstart定義コマンドに，開始するSPPのユーザサーバ名を指定します。

TP1/LiNKの場合

ユーザサーバ環境を設定する操作で，開始するSPPが自動起動するように設定します。

(b)　OpenTP1の開始後に任意に開始する場合

OpenTP1の開始後に任意に開始する場合は，dcsvstartコマンドの引数にSPPのユーザサーバ名を指定して実行します。

SPPのプロセスはメイン関数から開始します。メイン関数で呼び出す，SPPのサービス開始の関数（dc_rpc_mainloop関数【CBLDCRSV('MAINLOOP')】）が正常に実行されたことで，サービスを提供できる状態になります。

(3)　SPPの稼働中

開始させたSPPは，メモリを効率的に使うため，事前に指定したプロセスの状態で稼働しています。開始させたSPPを常駐プロセスで稼働させる場合と，非常駐プロセスで稼働させる場合があります。常駐プロセスとした場合は，サービス要求が来るとSPPの処理を開始します。非常駐プロセスとしてある場合でも，サービス要求が来るとプロセスを自動的に起動してSPPの処理を開始します。

UAPプロセスに関する設定内容については，「1.3.5　アプリケーションプログラムの環境設定」を参照してください。

(4)　SPPの終了

SPPが正常終了するのは，次に示す場合です。

OpenTP1が正常終了したとき

OpenTP1の稼働中に，SPPのユーザサーバ名を指定したdcsvstopコマンドを実行したとき

上記のどちらかの事象が起こると，メイン関数で呼び出したdc_rpc_mainloop関数がリターンして，SPPは終了します。

SPPのプロセスを，killコマンドで終了させないでください。

(5)　SPPの処理の概要

SPPのメイン関数では，次に示す関数を呼び出してください。

アプリケーションプログラムの開始（dc_rpc_open関数【CBLDCRPC('OPEN ')】）

SPPのサービス開始（dc_rpc_mainloop関数【CBLDCRSV('MAINLOOP')】）

SPPでトランザクションを開始しているときは，トランザクションをコミット（同期点を取得）してから，SPPを終了させてください。

また，SPPからMCFの関数を呼び出すときは，メイン関数でMCF環境のオープン（dc_mcf_open関数【CBLDCMCF('OPEN ')】）とMCF環境のクローズ（dc_mcf_close関数【CBLDCMCF('CLOSE ')】）を呼び出してください。

SPPの処理の概要を次の図に示します。

図1‒12　SPPの処理の概要（C言語の例）

1.2.3　メッセージを処理するUAP（MHP）

メッセージ送受信で使うUAPをメッセージ処理プログラム（MHP）といいます。MHPを使うと，MCFと接続されている他システムとメッセージ送受信形態で通信できます。メッセージ送受信については，「3.6　メッセージ送受信」を参照してください。

MHPでは，OpenTP1のメッセージ送受信機能の関数を使えます。また，MHPの処理からRPCを使ってSPPのサービスを要求できます。

MHPは，同じノードにMCFがあることが前提です。

MHPの概要を次の図に示します。

図1‒13　MHPの概要

(1)　MHPの構成

MHPは，SPPと同様にメイン関数とサービス関数から構成されます。

MCFで受信したメッセージにあるアプリケーション名によってスケジュールされるアプリケーションを，サービス関数（COBOL言語の場合はサービスプログラム）として作成します。このサービス関数を複数作成して，メイン関数（COBOL言語の場合はメインプログラム）で一つの実行形式ファイルにまとめます。そして，一つのメイン関数と複数のサービス関数から構成されるMHPの実行形式ファイルを，サービスグループとしてOpenTP1に定義します。

サービス関数動的ローディング機能は，複数のサービスをUAP共用ライブラリ化※して使うため，複数のサービスをメイン関数にまとめる作業は不要です。

注※

UAP共用ライブラリ化とは，UAPのソースファイルを翻訳（コンパイル）して作成したUAPオブジェクトファイルを結合（リンケージ）して，共用ライブラリとしてまとめることです。

MHPの構成を，スタブを使う場合とサービス関数動的ローディング機能を使う場合に分けて，それぞれ以降の図に示します。

図1‒14　MHPの構成（スタブを使う場合）

図1‒15　MHPの構成（サービス関数動的ローディング機能を使う場合）

(2)　MHPの開始

MHPを実行する場合，OpenTP1の開始と一緒に開始する方法と，OpenTP1の開始後に任意に開始する方法の2とおりがあります。OpenTP1の開始と一緒に開始すると，OpenTP1の開始と同時に，MHPの業務を開始できます。MHPの業務内容に応じて，開始する時期を選べます。

(a)　OpenTP1の開始と一緒に開始する場合

OpenTP1を開始する前に，OpenTP1と一緒に開始する指定をしておきます。ユーザサービス構成定義のdcsvstart定義コマンドに，開始するMHPのユーザサーバ名を指定します。

(b)　OpenTP1の開始後に任意に開始する場合

OpenTP1の開始後に任意に開始する場合は，dcsvstartコマンドの引数にMHPのユーザサーバ名を指定して実行します。

MHPはメイン関数から開始します。メイン関数で呼び出す，MHPのサービス開始の関数（dc_mcf_mainloop関数【CBLDCMCF('MAINLOOP')】）が正常に実行されたことで，メッセージを受信できる状態になります。なお，サービス開始の関数が呼び出される前にMHPが異常終了した場合，該当するユーザサービス定義（またはユーザサービスデフォルト定義）のholdオペランドおよびterm_watch_timeオペランドの指定値に従って処理します。

(3)　MHPの稼働中

開始させたMHPは，メモリを効率的に使うため，事前に指定したプロセスの状態で稼働しています。開始させたMHPを常駐プロセスで稼働させる場合と，非常駐プロセスで稼働させる場合があります。常駐プロセスとした場合は，サービス要求が来るとMHPの処理を開始します。非常駐プロセスとしてある場合でも，サービス要求が来るとプロセスを自動的に起動してMHPの処理を開始します。

UAPプロセスに関する設定内容については，「1.3.5　アプリケーションプログラムの環境設定」を参照してください。

(a)　メッセージを処理するMHPの業務の開始

MCFでメッセージを受信したあとに，該当するMHPのプロセスが起動されます。MHPはメッセージの先頭セグメントにあるアプリケーション名でスケジュールされます。OpenTP1内でUAPのサービスを認識するサービス名と，アプリケーション名は，MCFアプリケーション定義で対応付けます。

ほかのUAP（MHPまたはSPP）からdc_mcf_execap関数【CBLDCMCF('EXECAP ')】でMHPを起動させた場合には，次の2とおりの開始方法があります。

dc_mcf_execap関数を呼び出したUAPが正常終了（トランザクションがコミット）してから開始。

UAPがdc_mcf_execap関数を呼び出した直後から，設定した秒数が過ぎたあと，または設定した時刻になったら開始。

(b)　MCFイベント処理用MHPの業務の開始

MCFの障害やMHPの障害が起こった場合，MCFからエラー内容のデータを通知するためにメッセージが出力されます。これをMCFイベントといいます。MCFイベントが通知された場合に備えて，MCFイベント処理用MHPを作成しておくと，独自の障害対策処理ができます。MCFイベント処理用MHPは，通知されるMCFイベントのイベントコードに対応させて作成します。該当するMCFイベントが通知されたときに，MCFイベント処理用MHPが起動されます。MCFイベントについては，「3.10　MCFイベント」を参照してください。

(4)　MHPの終了

MHPが正常終了するのは，次に示す場合です。

OpenTP1が正常終了した場合

OpenTP1の稼働中に，MHPのユーザサーバ名を指定したdcsvstopコマンドを実行した場合

上記のどちらかの事象が起こると，メイン関数で呼び出したdc_mcf_mainloop関数がリターンして，MHPは終了します。

MHPのプロセスを，killコマンドで終了させないでください。

(5)　MHPの処理の概要

MHPのメイン関数では，次に示す関数を呼び出してください。

アプリケーションプログラムの開始（dc_rpc_open関数【CBLDCRPC('OPEN ')】）

MCF環境のオープン（dc_mcf_open関数【CBLDCMCF('OPEN ')】）

MHPのサービス開始（dc_mcf_mainloop関数【CBLDCMCF('MAINLOOP')】）

MCF環境のクローズ（dc_mcf_close関数【CBLDCMCF('CLOSE ')】）

MHPの処理の概要を次の図に示します。

図1‒16　MHPの処理の概要（C言語の例）

(6)　注意事項

MHPのサービス関数をRPCで呼び出すことはできません。

1.2.4　オフラインの業務をするUAP

オフラインのバッチ業務をするUAPを任意に作成できます。バッチ業務のほかにDAMファイルの初期化，DAMファイルの割り当てや削除の処理をするUAPは，オフライン環境で実行します。

オフラインの業務をするUAPで使えるOpenTP1の機能を次に示します。

DAMファイルの物理ファイルに対する処理

jnlrputコマンド出力ファイルのジャーナルデータの編集

オフラインの業務をするUAPでは，オンラインで使うOpenTP1の関数は使えません。また，オフラインの業務をするUAPとオンライン環境のUAP（SUP，SPP，MHP）では，サービス要求などの通信はできません。オフラインの業務をするUAPに，ほかのUAPに提供するサービスは作成できません。

オフラインの業務をするUAPの概要を次の図に示します。

図1‒17　オフラインの業務をするUAPの概要

(1)　オフラインの業務をするUAPの開始／終了

オフラインの業務をするUAPは，シェルから開始します。オフラインの業務をするUAPの開始と終了はユーザで管理します。

1.3　アプリケーションプログラムの作成

OpenTP1のUAPを作成する手順について説明します。UAPの作成手順を次の図に示します。

図1‒18　UAPの作成手順（スタブを使う場合）

図1‒19　UAPの作成手順（サービス関数動的ローディング機能を使う場合）

1.3.1　コーディング

OpenTP1のUAPをコーディングする場合，C言語，C++言語，またはCOBOL言語を使います。UAPでは，OpenTP1の機能のほかにも，OSの標準の機能やデータベース言語（SQL）を使えます。コーディングの規約については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。SQLのコーディングの規約については，該当するリファレンスマニュアルを参照してください。

(1)　C言語またはC++言語でコーディングする場合

(a)　C言語を使うとき

ANSI Cの形式，ANSI準拠前のK&Rの形式（Classic C）のどちらかに従ってコーディングします。UAPでOpenTP1の機能を使うときは，OpenTP1のライブラリ関数を呼び出します。

(b)　C++言語を使うとき

ANSI Cの形式でC++言語の仕様に従ってコーディングします。UAPでOpenTP1の機能を使うときは，OpenTP1のライブラリ関数を呼び出します。OpenTP1のライブラリ関数は，ヘッダファイル（dc×××.h）でC言語のリンケージを指定しているため，C++言語でコーディングしたUAPのリンケージの際にはC言語の関数としてリンケージされ動作します。

(c)　OpenTP1の関数の使い方

OSで標準的に提供する関数と同様，関数を呼び出すときには，引数を設定します。

関数が正常に実行されたかどうかは，戻ってくる値（リターン値）でわかります。関数には，リターン値を返す関数と返さない関数があります。

C言語でコーディングする場合の概要を次の図に示します。

図1‒20　C言語でコーディングする場合の概要

(2)　COBOL言語でコーディングする場合

COBOL言語を使うときは，COBOL85またはCOBOL2002の形式でコーディングします。UAPからOpenTP1の機能を使うときは，OpenTP1のライブラリ関数に対応したCOBOL-UAP作成用プログラムを使います。COBOL-UAP作成用プログラムを，COBOLのCALL文で呼び出して，UAPの処理からOpenTP1のライブラリに制御を移します。

CALL文の実行結果は，戻ってくる数値（ステータスコード）でわかります。COBOL-UAP作成用プログラムには，ステータスコードを返さないものもあります。

COBOL言語でコーディングする場合の概要を次の図に示します。

図1‒21　COBOL言語でコーディングする場合の概要

注※

TP1/Server Baseサンプルでは，COBOL-UAP作成用プログラムごとに，DATA DIVISIONのテンプレート（ひな形）を使えます。DATA DIVISIONのテンプレートについては，「8.8　COBOL言語用テンプレート」を参照してください。

(3)　注意事項

JNI（Java Native Interface）は使用できません。使用した場合の動作は保証できません。

OpenTP1のAPIは，すべてメインスレッド上で発行してください。UAPはマルチスレッドで作成できますが，OpenTP1が提供するAPIはスレッドセーフではないためです。メインスレッド以外でOpenTP1のAPIを発行すると，UAPが誤動作して異常終了するおそれがあります。ただし，次に示すAPIは，メインスレッド以外でも発行できます。

ee_で始まるTP1/EEのC言語インタフェース

CBLEEで始まるTP1/EEのCOBOL言語インタフェース

1.3.2　スタブの作成

OpenTP1で使うUAPを作成するときには，UAP間でサービスを要求できるようにするライブラリが必要となります。このライブラリをスタブといいます。スタブには，UAPのサービスに関する情報を指定します。また，通信相手の情報を作成する場合もあります。

スタブの作成方法については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

(1)　アプリケーションプログラムに結合させるスタブの種類

スタブには，サーバUAPに結合させるスタブとクライアントUAPに結合させるスタブがあります。

(a)　サーバUAPに結合させるスタブ

サーバUAPに結合させるスタブは，サービスを振り分ける関数と連動してUAPのサービスを実行できるようにします。サービスを振り分ける関数は，サーバUAPのメイン関数で呼び出します。サービスを振り分ける関数を，次に示します。

SPPの場合：dc_rpc_mainloop関数【CBLDCRSV('MAINLOOP')】

MHPの場合：dc_mcf_mainloop関数【CBLDCMCF('MAINLOOP')】

サーバUAPに結合させるスタブの概要を次の図に示します。

図1‒22　サーバUAPに結合させるスタブの概要

(b)　クライアントUAPに結合させるスタブ

クライアントUAPに結合させるスタブは，サーバUAPの情報を指定することで，サーバUAPと通信できるようにします。クライアントUAPにスタブが必要になるのは，XATMIインタフェースを使った通信の場合だけです。OpenTP1のRPCを使う場合は，クライアントUAPにスタブは必要ありません。

(2)　スタブが必要なUAP

UAPにスタブが必要かどうかは，UAPの種類や通信方法によって異なります。

OpenTP1のリモートプロシジャコールを使うUAP（SUP，SPP）

SPPにスタブが必要です。SUPにはスタブは必要ありません。

MHPの場合

MHPにはスタブが必要です。SPPと同様の手順でスタブを作成します。

XATMIインタフェースを使ってクライアント／サーバ形態の通信をする場合

クライアントUAP（SUP，SPP）とサーバUAP（SPP）の両方に，スタブが必要です。

オフラインの業務をするUAPは，サービス関数がないので，スタブを作成する必要はありません。

(3)　スタブの作成手順

スタブを作成するときは，UAPに関する情報の定義を格納したファイル（RPCインタフェース定義ファイル※）を作成します。そして，RPCインタフェース定義ファイルを引数にして，スタブを生成するコマンドを実行します。スタブを生成するコマンドを，次に示します。

TCP/IP通信をするUAPの場合：stbmakeコマンド

OSI TP通信をするUAPの場合：tpstbmkコマンド

スタブを生成するコマンドを実行すると，スタブのソースファイル（C言語のソースファイル）が作成されます。このファイルをC言語のコンパイラで翻訳して，UAPのオブジェクトファイルに結合させます。

MHPをANSI C形式，およびC++形式でコーディングした場合，そのMHPに結合するスタブの翻訳時には，DCMHPを定義してください。

スタブの内容を変更するときは，UAPを作成する一連の作業をやり直します。定義ファイルの内容を変更して，スタブを作り直してから，コンパイルし直したUAPのオブジェクトファイルに結合させてください。

注※

XATMIインタフェースのスタブの場合は，XATMIインタフェース定義ファイルといいます。

スタブの作成手順を次の図に示します。

図1‒23　スタブの作成手順

1.3.3　翻訳と結合（スタブを使用する場合）

作成したプログラムの翻訳（コンパイル）と結合（リンケージ）の手順について説明します。UAPをコンパイル，リンケージして，実行形式ファイルとします。コンパイルとリンケージの手順については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

(1)　翻訳（コンパイル）

コンパイルするプログラムを次に示します。

UAPのソースファイル（メイン関数，サービス関数）

スタブ（UAPに必要な場合）

C言語のプログラムはC言語のコンパイラで，COBOL言語で作成したプログラムは該当するCOBOL言語のコンパイラで翻訳します。

(2)　結合（リンケージ）

コンパイルして作成したオブジェクトファイルを，OpenTP1のライブラリなど必要なファイルとリンケージします。OpenTP1以外のRMを使う場合は，OpenTP1以外のRMが指定するライブラリとリンケージします。OpenTP1以外のRMをXAインタフェースで使う場合，次の手順でUAPにライブラリをリンケージします。

OpenTP1以外のRMのリソースマネジャ識別子をtrnmkobjコマンドに指定して，トランザクション制御用オブジェクトファイルを作成します。

作成したトランザクション制御用オブジェクトファイルを，UAPにリンケージします。

(3)　注意事項

OSがHP-UXの場合，リンケージ時のバインドモードには必ず"immediate"を指定してください。"immediate"以外のバインドモードで作成した実行形式ファイルをOpenTP1のUAPとして使った場合，システムの動作は保証しません。作成したUAPのバインドモードが"immediate"かどうかは，OSのchatrコマンドで確認してください。

1.3.4　翻訳と結合（サービス関数動的ローディング機能を使用する場合）

作成したプログラムの翻訳（コンパイル），結合（リンケージ），およびUAP共用ライブラリ化※の手順について説明します。

まず，UAPのメイン関数をコンパイル，リンケージして実行形式ファイルとします。次に，UAPのサービス関数をUAP共用ライブラリ化※します。コンパイルとリンケージの手順については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

注※

UAP共用ライブラリ化とは，UAPのソースファイルを翻訳（コンパイル）して作成したUAPオブジェクトファイルを結合（リンケージ）して，共用ライブラリとしてまとめることです。

(1)　翻訳（コンパイル）

コンパイルするプログラムを次に示します。

UAPのソースファイル（メイン関数，サービス関数）

C言語のプログラムはC言語のコンパイラで，COBOL言語で作成したプログラムは該当するCOBOL言語のコンパイラで翻訳します。

(2)　結合（リンケージ）

UAPのメイン関数のソースファイルをコンパイルして作成したオブジェクトファイルを，OpenTP1のライブラリなど必要なファイルとリンケージします。OpenTP1以外のRMを使う場合は，OpenTP1以外のRMが指定するライブラリとリンケージします。OpenTP1以外のRMをXAインタフェースで使う場合，次の手順でUAPにライブラリをリンケージします。

OpenTP1以外のRMのリソースマネジャ識別子をtrnmkobjコマンドに指定して，トランザクション制御用オブジェクトファイルを作成します。

作成したトランザクション制御用オブジェクトファイルを，UAPにリンケージします。

(3)　UAP共用ライブラリの作成

UAPのサービス関数のソースファイルをコンパイルして作成したオブジェクトファイルを，共用ライブラリ化します。このとき，(2)と同様に，OpenTP1のライブラリなど必要なファイルとリンケージします。コンパイルオプションおよびリンケージオプションについては，TP1/Server Baseサンプル（make_svdlファイル）を参照してください。

(4)　注意事項

OSがHP-UXの場合，リンケージ時のバインドモードには必ず"immediate"を指定してください。"immediate"以外のバインドモードで作成した実行形式ファイルをOpenTP1のUAPとして使った場合，システムの動作は保証しません。作成したUAPのバインドモードが"immediate"かどうかは，OSのchatrコマンドで確認してください。

1.3.5　アプリケーションプログラムの環境設定

作成したUAPの実行形式ファイルを，OpenTP1のユーザサーバとして使えるように，環境設定します。

(1)　UAPを格納するディレクトリ

作成したUAPの実行形式ファイルは，$DCDIR/aplib/ディレクトリ（$DCDIRは，OpenTP1ホームディレクトリを示します）に格納します。

(2)　UAPの登録

UAPの実行形式ファイルを，OpenTP1に登録します。OpenTP1のUAPは，サービスを提供することからユーザサーバといいます。

(a)　UAPの登録方法

OpenTP1にUAPを登録するときに，実行環境を設定します。実行環境を設定する方法を次に示します。

TP1/Server Baseの場合

ユーザサービス定義で設定します。

TP1/LiNKの場合

UNIXの場合はdcsysset -uコマンドを，Windowsの場合は［アプリケーション管理］アイコンを使います。

(b)　ユーザサーバ名

OpenTP1でUAPを操作するときに使う名称をユーザサーバ名といいます。ユーザサーバ名は，次のようになります。

TP1/Server Baseの場合

ユーザサービス定義のファイル名です。

TP1/LiNKの場合

UAPの環境を設定するときに，実行形式ファイル名に対応させてユーザサーバ名を任意で付けます。

(3)　UAPの名称の関係

UAPとして作成するプログラムの名称について説明します。

UAPの実行形式ファイル名

UAPのオブジェクトファイルをライブラリとリンケージするときに，リンケージのコマンドにオプションで設定した名称です。

ユーザサーバ名

UAPをOpenTP1に登録するときに設定した名称です。dcsvstartコマンドの引数に使用します。ユーザサーバ名は，1〜8文字で設定します。

サービスグループ名，サービス名

OpenTP1のリモートプロシジャコールやXATMIインタフェースの通信で，サービスを要求する関数の引数に設定する名称です。ユーザサーバ名をOpenTP1に登録するときに一緒に指定します。

サービスグループ名は，UAPの実行形式ファイル単位に名称を付けます。

サービス名は，サービス関数の関数名です。

アプリケーション名

TP1/Message Controlで受け取ったメッセージを処理するときに，該当するメッセージを処理するアプリケーションであることを識別する名称です。MHPのサービス関数をアプリケーション名として登録します。サービス名とアプリケーション名の対応はMCFアプリケーション定義に指定します。

1.3.6　ユーザサーバの負荷分散とスケジュール

UAP（ユーザサーバ）を効率良く使うための機能（マルチサーバ）とUAPのスケジュール方法について説明します。

OpenTP1のシステムサービス，またはユーザサーバを実行するときには，OSの作業領域を使用します。この作業領域の処理をプロセスといいます。ユーザサーバを実行して生成されるプロセスを特にユーザサーバプロセス，UAPプロセス，または単にプロセスといいます。OpenTP1では，プロセスが必要以上に増えたり減ったりしないように，使うプロセスの総数を制御しています。

ユーザサーバのプロセスを制御するには，ユーザサーバを事前に開始していることが前提です。OpenTP1と一緒に開始させておくか，dcsvstart -uコマンドで開始させておきます。

(1)　マルチサーバ

実行中のユーザサーバに対して，さらにサービス要求が来た場合でも，ユーザサーバの処理を新しい別のプロセスで実行できます。このように，一つのユーザサーバの処理を，別のプロセスで並行して実行する機能をマルチサーバといいます。

マルチサーバを使えるのは，スケジュールキューを使うSPP（キュー受信型サーバ）です。ソケット受信型サーバの場合はマルチサーバを使えません。ソケット受信型サーバには，使うプロセスは一つだけと指定してください。

(2)　常駐プロセスと非常駐プロセス

マルチサーバを指定したUAPのプロセスを，OpenTP1の稼働中にいつも確保しておくことも，動的に確保することもできます。いつも確保されているプロセスを常駐プロセスといいます。また，稼働中には確保されていなくて，必要に応じて起動されるプロセスを非常駐プロセスといいます。

プロセスを非常駐プロセスと設定しておくと，OpenTP1システム内のメモリ領域を効率良く使えます。また，プロセスを常駐プロセスと設定しておくと，そのユーザサーバの処理は非常駐プロセスに比べて速くなります。

システムのメモリに空きがない場合，非常駐プロセスは稼働中の非常駐プロセスが終了してから実行されます。

非常駐プロセスを使用すると，一時的※に最大でユーザサービス定義のparallel_countオペランドの指定値の2倍のプロセス数が起動されることがあります。

注※

終了しようとしているプロセスが，dc_rpc_mainloop関数またはdc_mcf_mainloop関数の終了後からdc_rpc_close関数終了までの区間にある場合で，新たなサービス要求を受け付けたタイミングです。

また，非常駐プロセスであってもプロセス起動による性能への影響を最小限にとどめるため，同一プロセスで続けてサービス要求を処理する場合があります。そのため，ユーザサーバはリエントラントできるプログラム構造で作成する必要があります。

(3)　プロセスの設定方法

プロセスを常駐とするか非常駐とするかは，ユーザサーバの起動プロセス数で，事前に設定しておきます。設定したプロセスの数だけ，並行にプロセスを起動できます。設定する方法を次に示します。

TP1/Server Baseの場合

ユーザサービス定義のparallel_countオペランドで，使うプロセスの合計（常駐プロセス数と非常駐プロセス数）を設定します。

TP1/LiNKの場合

UAPの実行環境を設定するときに，使うプロセスの数（常駐プロセス数と非常駐プロセス数）を設定します。

常駐プロセスを複数個指定していれば，指定した数だけ並行してプロセスが起動されます。また，非常駐プロセスを複数個指定していれば，指定した数だけ動的にプロセスが起動されます。

(4)　マルチサーバ負荷バランス

スケジュールキューにあるサービスの要求数に応じて，非常駐プロセスの数を増やしたり減らしたりする機能をマルチサーバ負荷バランス機能といいます。

非常駐プロセスをいつ起動するかは，ユーザサービス定義のbalance_countオペランドに指定する値で決まります。（balance_countオペランドに指定した値×起動中のプロセス）の数を超えてサービス要求が滞留したときに，OpenTP1は非常駐プロセスを起動します。スケジュールキューに滞留しているサービス要求の数が0になると，OpenTP1は非常駐プロセスを終了させます。

非常駐プロセスを起動するタイミングの値を指定する方法を次に示します。

TP1/Server Baseの場合

ユーザサービス定義のbalance_countオペランドに設定します。

TP1/LiNKの場合

UAPの実行環境を設定するときのサービスの最大滞留数が，上記のbalance_countオペランドの値になります。

(5)　非常駐UAPプロセスのリフレッシュ機能

非常駐プロセスを使用する場合，一つのサービス要求ごとに実行プロセスを起動し直すことができます。この機能を，非常駐UAPプロセスのリフレッシュ機能といいます。この機能を使用することで，リエントラント構造ではないUAPの実行もできるようになります。

この機能を使用するためには，ユーザサービス定義またはユーザサービスデフォルト定義に，scd_refresh_processオペランドを指定します。また，この機能は1プロセスが処理するサービス要求数（ユーザサービス定義のbalance_countオペランドの指定値）が0の場合にだけ使用できます。

非常駐UAPプロセスのリフレッシュ機能を使用しない場合と使用する場合の動作，およびこの機能を使用する場合の注意事項について説明します。

(a)　非常駐UAPプロセスのリフレッシュ機能を使用しない場合の動作

非常駐UAPプロセスのリフレッシュ機能を使用しない場合の動作を，次の図に示します。図中の番号と以降の説明の番号は対応しています。

図1‒24　非常駐UAPプロセスのリフレッシュ機能を使用しない場合の動作

SPPまたはMHPのスケジュールキューにサービス要求が登録されたため，プロセスIDが10のSPPまたはMHPプロセスを起動します。また，一つ目のサービス要求について，サービス関数を実行します。

サービス関数の実行後，SPPまたはMHPのスケジュールキューにサービス要求がある場合は，そのプロセス上で再度サービス関数を実行します。

以降，スケジュールキューからサービス要求がなくなるまで，処理を繰り返します。

SPPまたはMHPのスケジュールキューにサービス要求がなくなったので，プロセスが終了となります。

(b)　非常駐UAPプロセスのリフレッシュ機能を使用する場合の動作

非常駐UAPプロセスのリフレッシュ機能を使用する場合の動作を，次の図に示します。図中の番号と以降の説明の番号は対応しています。

図1‒25　非常駐UAPプロセスのリフレッシュ機能を使用する場合の動作

SPPまたはMHPのスケジュールキューにサービス要求が登録されたため，プロセスIDが10のSPPまたはMHPプロセスを起動します。また，一つ目のサービス要求についてサービス関数を実行したあと，プロセス起動処理を実行して自プロセスは終了します。

プロセスIDが10のSPPまたはMHPで実行したプロセス起動処理によって，prcdはプロセスIDが20のSPPまたはMHPプロセスを起動します。また，二つ目のサービス要求についてサービス関数を実行したあと，プロセス起動処理を実行して自プロセスは終了します。

プロセスIDが20のSPPまたはMHPで実行したプロセス起動処理によって，prcdはプロセスIDが30のSPPまたはMHPプロセスを起動します。また，三つ目のサービス要求についてサービス関数を実行したあと，プロセス起動処理を実行して自プロセスは終了します。

以降，スケジュールキューからサービス要求がなくなるまで，処理を繰り返します。

(c)　非常駐UAPプロセスのリフレッシュ機能使用時の注意事項

起動した時点で常駐プロセスがある構成（常駐プロセス数に1以上を指定する）のサーバを，scdchprcコマンドを使用して非常駐プロセスだけで構成される（常駐プロセス数に0を，最大プロセス数に1以上を指定する）サーバに変更しても，この機能の対象にはなりません。

起動した時点で非常駐プロセスだけで構成される（常駐プロセス数に0を，最大プロセス数に1以上を指定する）サーバを，scdchprcコマンドを使用して一つ以上の常駐プロセスがある構成（常駐プロセス数に１以上を指定する）のサーバに変更した場合は，常駐プロセスおよび非常駐プロセスの両方がこの機能の対象になります。

OpenTP1システムで同時に起動されるプロセス数が一時的に増加する可能性があるため，この機能を使用する場合は十分な検証を実施し，必要となる最大同時起動サーバプロセス数（プロセスサービス定義のprc_process_countオペランドの指定値）を見積もってください。

検証，見積もり方法を次に示します。

現状のOpenTP1を起動して次のコマンドを実行し，表示されたサーバの中から「_」付きのサーバ数を数えます。

prcls -a

クライアントサービス定義のparallel_countオペランドの指定値である，最大プロセス数の合計値を2倍にした値を算出します。

手順1.および2.の合計値以上の値を，prc_process_countオペランドに設定します。

システム構成によっては，UAPプロセスの起動と停止が頻繁に発生する可能性があります。その場合はシステム資源（CPU，メモリ，動的ポートなど）が枯渇するおそれがあるため，十分な検証を実施し，システム資源を見積もってください。

それぞれのシステム資源の検証方法を次に示します。

CPUメモリ

高負荷テストや長時間連動試験中に，パフォーマンスモニタなどでCPUやメモリの状態を定期的に確認し，不足することがないか検証してください。

TCP/IPの動的ポート

OpenTP1のUAPは，起動時にTCP/IPの動的ポートを使用します。UAP停止時には動的ポートを開放しますが，TCP/IPの仕様で一定時間（TIME_WAIT状態の間）資源を確保します。そのため，OSで使用できる動的ポート数を，一定時間内で使い切らないようにしてください。高負荷テストや長時間連動試験中にnetstatコマンドを定期的に実行し，OSで使用できる動的ポート数の使用状況を監視して不足していないか検証してください。

プロセスの起動とサーバマシンのログオフ処理が重なると，OpenTP1がKFCA01820-Eメッセージを出力し，プロセス初期化エラーになることがあります。そのため，UAPプロセスの起動と停止が頻繁に発生するシステムでは，該当するサーバマシンでのログオフ操作を控えてください。

プログラム言語としてCOBOL2002を使用する場合は，コンパイルオプション「-CBLVALUE」を指定したコンパイルでUAPを作成してください。「-CBLVALUE」を指定することでプロセス再起動ごとにVALUE句の指定がないデータ項目が初期化された状態となります。コンパイルオプションの詳細については，COBOL2002のマニュアルを参照してください。

(6)　スケジュールの優先度

一つ一つのユーザサーバには，スケジュールの優先度（スケジュールプライオリティ）を付けられます。優先度が高いユーザサーバの非常駐プロセスは，ほかの非常駐プロセスに比べて優先的にスケジュールされます。

スケジュールの優先度は，ユーザサーバで使うプロセスを設定するときに，一緒に設定します。

プロセスの負荷分散を次の図に示します。

図1‒26　プロセスの負荷分散

(7)　ノード間負荷バランス機能

同じサービスグループ名のユーザサーバを複数のノードに配置しておくと，サービスを要求されたときに，どのノードのユーザサーバでも処理できます。これによって，ノード間で負荷分散できます。これをノード間負荷バランス機能といいます。ノード間負荷バランス機能を使うための環境設定は必要ありません。複数のノードで同じサービスグループ名のユーザサーバを開始しておけば，OpenTP1で自動的に振り分けます。

OpenTP1システム内の同一サービスグループに，マルチスケジューラ機能を使用しているユーザサーバと，マルチスケジューラ機能を使用していないユーザサーバが混在する場合，マルチスケジューラ機能を使用しているユーザサーバが高負荷状態でも，マルチスケジューラ機能を使用していないユーザサーバには負荷分散されません。マルチスケジューラ機能を使用していないユーザサーバに負荷分散するには，スケジュールサービス定義のscdmulti定義コマンドに-tオプションを指定してください。scdmulti定義コマンドの詳細については，マニュアル「OpenTP1 システム定義」のスケジュールサービス定義を参照してください。

ノード間負荷バランス機能で負荷を分散できるノードの数は，最大128です。

ノード間負荷バランス機能では，ノードのスケジュール状態に応じて，より効率的に処理できるノードへ負荷を分散させます。ノード間負荷バランス機能の環境で，サービスを要求したUAPと同じノードにあるユーザサーバを優先的にスケジュールしたい場合には，そのノードのスケジュールサービス定義にscd_this_node_firstオペランドにYを指定しておいてください。

ノード間負荷バランス機能の概要を次の図に示します。

図1‒27　ノード間負荷バランス機能の概要

(8)　ノード間負荷バランス拡張機能

ユーザは次に示す指定ができます。

LEVEL0のノードへのスケジュール比率の指定

スケジュールサービス定義のschedule_rateオペランドを指定することによって，負荷レベルがLEVEL0のノードにスケジュールする比率（%）を指定できます。

負荷監視インターバル時間の指定

ユーザサービス定義およびユーザサービスデフォルト定義のloadcheck_intervalオペランドを指定することによって，サービスグループごとに負荷監視インターバル時間を指定できます。

負荷レベルのしきい値の指定

ユーザサービス定義およびユーザサービスデフォルト定義のlevelup_queue_countオペランドおよびleveldown_queue_countオペランドを指定することによって，サービスグループごとにサービス要求滞留数によって負荷レベルを決定するしきい値を指定できます。

通信障害時のリトライ回数の指定

通常，サービス要求のスケジューリング時に通信障害が発生すると，再スケジュールしないでエラーリターンします。スケジュールサービス定義のscd_retry_of_comm_errorオペランドを指定することによって，通信障害が発生したノード以外へスケジュールするリトライ回数を指定できます。

なお，この機能は，TP1/Extension 1をインストールしていることが前提です。TP1/Extension 1をインストールしていない場合の動作は保証できませんので，ご了承ください。

(9)　マルチスケジューラ機能

クライアントUAPから，他ノードのキュー受信型サーバ（スケジュールキューを使うSPP）にサービスを要求した場合，要求先サーバが存在するノードのスケジューラデーモンが，いったんサービス要求メッセージを受信し，該当するキュー受信型サーバのスケジュールキューに格納します。スケジューラデーモンは，スケジュールサービスを提供するシステムデーモンのことです。

スケジューラデーモンは，OpenTP1システムごとに1プロセスです。そのため，システムの大規模化，マシンやネットワークの高性能化などに伴って，従来のスケジューラデーモンだけでは効率良くスケジューリングできないことがあります。従来のスケジューラデーモンだけでは効率良くスケジューリングできない場合については，「付録C　マルチスケジューラ機能の検討が必要なシステム構成例」を参照してください。

従来のスケジューラデーモン（これ以降マスタスケジューラデーモンといいます）とは別に，サービス要求受信専用デーモン（これ以降マルチスケジューラデーモンといいます）を複数プロセス起動し，サービス要求メッセージ受信処理を並行動作させることによって，受信処理の競合によるスケジューリング遅延を回避できます。この機能をマルチスケジューラ機能といいます。

なお，この機能は，TP1/Extension 1をインストールしていることが前提です。TP1/Extension 1をインストールしていない場合の動作は保証できませんので，ご了承ください。

マルチスケジューラ機能を使用するには，次の定義を指定する必要があります。

RPC受信側

スケジュールサービス定義　scdmulti

ユーザサービス定義　scdmulti

RPC送信側

ユーザサービス定義　multi_schedule

また，幾つかのマルチスケジューラデーモンをキュー受信型サーバごとにグループ化できます。これによって，異なるサーバ間でサービス要求メッセージの受信処理が競合するのを回避できます。マルチスケジューラデーモンをグループ化して使用する場合，サーバ側でユーザサービス定義 scdmultiに-gオプションを指定する必要があります。

OpenTP1起動時に，スケジュールサービスを提供するシステムデーモンとして，マスタスケジューラデーモンに加え，定義に指定したマルチスケジューラデーモンをウェルノウンポート番号で起動します。なお，TP1/Clientからマルチスケジューラ機能を使用してサービスを要求する場合については，マニュアル「OpenTP1 クライアント使用の手引 TP1/Client/W，TP1/Client/P編」を参照してください。

マルチスケジューラ機能を使用したRPCについては「2.1.16　マルチスケジューラ機能を使用したRPC」を参照してください。

マルチスケジューラ機能の使用例を次の図に示します。

図1‒28　マルチスケジューラ機能の使用例

SPP1は，短いサービス要求メッセージを扱うため，マルチスケジューラ機能を使用しないで，マスタスケジューラデーモンにスケジューリングさせます（図の1.）。

SPP2は，長大サービス要求メッセージを扱うため，OpenTP1のノード1とノード2に分散させ，ノード1にあるグループ1のマルチスケジューラデーモン1，またはノード2にあるグループ1のマルチスケジューラデーモン1，2にスケジューリングさせます（図の2.）。

SPP3は，短いサービス要求メッセージを扱いますが，サービス要求数が多いため，OpenTP1のノード1とノード2に分散させ，ノード1にあるグループ2のマルチスケジューラデーモン2，3，またはノード2にあるグループ2のマルチスケジューラデーモン3にスケジューリングさせます（図の3.）。

1.4　OpenTP1のライブラリ関数

1.4.1　アプリケーションプログラミングインタフェースの機能

OpenTP1のライブラリ関数を使ってできる機能を，次に示します。

(1)　OpenTP1の基本機能（TP1/Server Base，TP1/LiNK）

リモートプロシジャコール

UAP間で，関数呼び出しと同様の方法で通信できます。

トランザクション制御

UAPの処理をトランザクションとして制御できます。

システム運用の管理

UAPからコマンドを実行したり，ユーザサーバの状態を報告したりできます。

メッセージログの出力

UAPからユーザ任意の情報を，メッセージログとして出力できます。

ユーザジャーナルの取得

ユーザジャーナル（UJ）を，システムジャーナルファイルに取得できます。

ジャーナルデータの編集

jnlrputコマンドの実行結果を格納したファイルにあるジャーナルデータを，編集できます。

リアルタイム統計情報の取得

UAP内の任意区間で，リアルタイム統計情報を取得できます。

(2)　TP1/Message Controlを使う場合の機能

メッセージ送受信

広域網，およびTCP/IPで接続されたシステム間で，メッセージ送受信形態の通信ができます。

(3)　ユーザデータを使う場合の機能

DAMファイルサービス（TP1/FS/Direct Access）

OpenTP1専用のユーザファイルを，直接編成ファイル（DAMファイル）として使えるようにします。

TAMファイルサービス（TP1/FS/Table Access）

OpenTP1専用のユーザファイルを，テーブルアクセス法による直接編成ファイル（TAMファイル）として使えるようにします。

ISAMファイルサービス※（ISAM，ISAM/B）

X/OpenのISAMモデルに準拠した，索引順編成ファイル（ISAMファイル）を使えるようにします。

ISTサービス（TP1/Shared Table Access）

共用メモリ上にあるテーブル（ISTテーブル）を，複数のOpenTP1システムで共用できるようにします。ISTサービスの場合，ユーザファイルの実体はなく，メモリ上のISTテーブルにデータが格納されます。

資源の排他制御

任意のファイル（UNIXファイル）を，OpenTP1のAPIで排他制御します。

注※

ISAMファイルサービスについては，マニュアル「索引順編成ファイル管理 ISAM」を参照してください。

(4)　X/Openに準拠したアプリケーションプログラミングインタフェース

XATMIインタフェース

X/Openに準拠したAPIで，クライアント／サーバ形態の通信ができます。

TXインタフェース

X/Openに準拠したAPIで，トランザクションを制御できます。

(5)　特殊な形態で使う機能

特殊な形態で使う機能の関数を，次に示します。

(a)　TP1/Multiを使う場合の機能

マルチノード機能

クラスタ／並列システム形態のOpenTP1のUAPで，各種の機能を使えます。

(b)　オンラインテスタ（TP1/Online Tester）を使う場合の機能

オンラインテスタの管理

ユーザサーバのテスト状態を，UAPから関数を使って知ることができます。

1.4.2　OpenTP1のライブラリ関数の一覧

(1)　ライブラリ関数の一覧

OpenTP1のライブラリ関数の一覧を表1-1〜表1-5に示します。

表1‒1　OpenTP1のライブラリ関数の一覧（OpenTP1の基本機能の関数）

機能

ライブラリ関数名

C言語ライブラリ

COBOL-UAP作成用プログラム

リモートプロシジャコール

アプリケーションプログラムの開始

dc_rpc_open

CBLDCRPC('OPEN ')

SPPのサービス開始

dc_rpc_mainloop

CBLDCRSV('MAINLOOP')

遠隔サービスの要求

dc_rpc_call

CBLDCRPC('CALL ')

通信先を指定した遠隔サービスの呼び出し※1

dc_rpc_call_to

−

処理結果の非同期受信

dc_rpc_poll_any_replies

CBLDCRPC('POLLANYR')

エラーが発生した非同期応答型RPC要求の記述子の取得

dc_rpc_get_error_descriptor

CBLDCRPC('GETERDES')

処理結果の受信の拒否

dc_rpc_discard_further_replies

CBLDCRPC('DISCARDF')

特定の処理結果の受信の拒否

dc_rpc_discard_specific_reply

CBLDCRPC('DISCARDS')

サービス関数のリトライ

dc_rpc_service_retry

CBLDCRPC('SVRETRY ')

サービス要求のスケジュールプライオリティの設定

dc_rpc_set_service_prio

CBLDCRPC('SETSVPRI')

サービス要求のスケジュールプライオリティの参照

dc_rpc_get_service_prio

CBLDCRPC('GETSVPRI')

サービスの応答待ち時間の参照

dc_rpc_get_watch_time

CBLDCRPC('GETWATCH')

サービスの応答待ち時間の更新

dc_rpc_set_watch_time

CBLDCRPC('SETWATCH')

クライアントUAPのノードアドレスの取得

dc_rpc_get_callers_address

CBLDCRPC('GETCLADR')

ゲートウェイのノードアドレスの取得

dc_rpc_get_gateway_address

CBLDCRPC('GETGWADR')

CUPへの一方通知

dc_rpc_cltsend

CBLDCRPC('CLTSEND ')

アプリケーションプログラムの終了

dc_rpc_close

CBLDCRPC('CLOSE ')

リモートAPI機能

rapリスナーとのコネクション確立

dc_rap_connect

CBLDCRAP('CONNECT ')

CBLDCRAP('CONNECTX')

rapリスナーとのコネクション解放

dc_rap_disconnect

CBLDCRAP('DISCNCT ')

トランザクション制御

トランザクションの開始

dc_trn_begin

CBLDCTRN('BEGIN ')

連鎖モードのコミット

dc_trn_chained_commit

CBLDCTRN('C-COMMIT')

連鎖モードのロールバック

dc_trn_chained_rollback

CBLDCTRN('C-ROLL ')

非連鎖モードのコミット

dc_trn_unchained_commit

CBLDCTRN('U-COMMIT')

非連鎖モードのロールバック

dc_trn_unchained_rollback

CBLDCTRN('U-ROLL ')

現在のトランザクションに関する情報の報告

dc_trn_info

CBLDCTRN('INFO ')

リソースマネジャ接続先選択

dc_trn_rm_select

CBLDCTRN('RMSELECT')

システム運用の管理

運用コマンドの実行

dc_adm_call_command

CBLDCADM('COMMAND ')

ユーザサーバの開始処理完了の報告

dc_adm_complete

CBLDCADM('COMPLETE')

ユーザサーバの状態の報告

dc_adm_status

CBLDCADM('STATUS ')

監査ログの出力

監査ログの出力

dc_log_audit_print

CBLDCADT('PRINT ')

メッセージログの出力

メッセージログの出力

dc_logprint

CBLDCLOG('PRINT ')

ユーザジャーナルの取得

ユーザジャーナルの取得

dc_jnl_ujput

CBLDCJNL('UJPUT ')

ジャーナルデータの編集※2

jnlrput出力ファイルのクローズ

−

CBLDCJUP('CLOSERPT')

jnlrput出力ファイルのオープン

−

CBLDCJUP('OPENRPT ')

jnlrput出力ファイルからジャーナルデータの入力

−

CBLDCJUP('RDGETRPT')

性能検証用トレース

ユーザ固有の性能検証用トレースの取得

dc_prf_utrace_put

CBLDCPRF('PRFPUT ')

性能検証用トレース取得通番の通知

dc_prf_get_trace_num

CBLDCPRF('PRFGETN ')

リアルタイム統計情報サービス

任意区間でのリアルタイム統計情報の取得

dc_rts_utrace_put

CBLDCRTS('RTSPUT ')

（凡例）

−：該当しません。

注※1

COBOL-UAP作成用プログラムは使えません。

注※2

ジャーナルデータの編集では，C言語のAPIは使えません。

表1‒2　OpenTP1のライブラリ関数の一覧（TP1/Message Controlの関数）

機能

ライブラリ関数名

C言語ライブラリ

COBOL-UAP作成用プログラム

メッセージ送受信

MCF環境のオープン

dc_mcf_open

CBLDCMCF('OPEN ')

MHPのサービス開始

dc_mcf_mainloop

CBLDCMCF('MAINLOOP')

メッセージの受信

dc_mcf_receive

CBLDCMCF('RECEIVE ')

応答メッセージの送信

dc_mcf_reply

CBLDCMCF('REPLY ')

メッセージの送信

dc_mcf_send

CBLDCMCF('SEND ')

メッセージの再送

dc_mcf_resend

CBLDCMCF('RESEND ')

同期型のメッセージ受信

dc_mcf_recvsync

CBLDCMCF('RECVSYNC')

同期型のメッセージ送信

dc_mcf_sendsync

CBLDCMCF('SENDSYNC')

同期型のメッセージ送受信

dc_mcf_sendrecv

CBLDCMCF('SENDRECV')

一時記憶データの受け取り

dc_mcf_tempget

CBLDCMCF('TEMPGET ')

一時記憶データの更新

dc_mcf_tempput

CBLDCMCF('TEMPPUT ')

継続問い合わせ応答の終了

dc_mcf_contend

CBLDCMCF('CONTEND ')

アプリケーションプログラムの起動

dc_mcf_execap

CBLDCMCF('EXECAP ')

アプリケーション情報通知

dc_mcf_ap_info

CBLDCMCF('APINFO ')

UOCアプリケーション情報通知

dc_mcf_ap_info_uoc

−

ユーザタイマ監視の設定

dc_mcf_timer_set

CBLDCMCF('TIMERSET')

ユーザタイマ監視の取り消し

dc_mcf_timer_cancel

CBLDCMCF('TIMERCAN')

MHPのコミット

dc_mcf_commit

CBLDCMCF('COMMIT ')

MHPのロールバック

dc_mcf_rollback

CBLDCMCF('ROLLBACK')

MCF環境のクローズ

dc_mcf_close

CBLDCMCF('CLOSE ')

MCF通信サービスの状態取得

dc_mcf_tlscom

CBLDCMCF('TLSCOM ')

コネクションの状態取得

dc_mcf_tlscn

CBLDCMCF('TLSCN ')

コネクションの確立

dc_mcf_tactcn

CBLDCMCF('TACTCN ')

コネクションの解放

dc_mcf_tdctcn

CBLDCMCF('TDCTCN ')

サーバ型コネクションの確立要求の受付状態取得

dc_mcf_tlsln

CBLDCMCF('TLSLN ')

サーバ型コネクションの確立要求の受付開始

dc_mcf_tonln

CBLDCMCF('TONLN ')

サーバ型コネクションの確立要求の受付終了

dc_mcf_tofln

CBLDCMCF('TOFLN ')

アプリケーションに関するタイマ起動要求の削除

dc_mcf_adltap

CBLDCMCF('ADLTAP ')

論理端末の状態取得

dc_mcf_tlsle

CBLDCMCF('TLSLE ')

論理端末の閉塞

dc_mcf_tdctle

CBLDCMCF('TDCTLE ')

論理端末の閉塞解除

dc_mcf_tactle

CBLDCMCF('TACTLE ')

論理端末の出力キュー削除

dc_mcf_tdlqle

CBLDCMCF('TDLQLE ')

（凡例）

−：該当しません。

表1‒3　OpenTP1のライブラリ関数の一覧（ユーザデータを操作する関数）

機能

ライブラリ関数名

C言語ライブラリ

COBOL-UAP作成用プログラム

DAMファイルサービス

論理ファイルのオープン

dc_dam_open

CBLDCDAM('DCDAMSVC','OPEN')

論理ファイルからブロックの入力

dc_dam_read

CBLDCDAM('DCDAMSVC','READ')

論理ファイルのブロックの更新

dc_dam_rewrite

CBLDCDAM('DCDAMSVC','REWT')

論理ファイルへブロックの出力

dc_dam_write

CBLDCDAM('DCDAMSVC','WRIT')

論理ファイルのクローズ

dc_dam_close

CBLDCDAM('DCDAMSVC','CLOS')

論理ファイルの閉塞

dc_dam_hold

CBLDCDAM('DCDAMSVC','HOLD')

論理ファイルの閉塞の解除

dc_dam_release

CBLDCDAM('DCDAMSVC','RLES')

論理ファイルの状態の参照

dc_dam_status

CBLDCDAM('DCDAMSVC','STAT')

回復対象外DAMファイル使用の開始

dc_dam_start

CBLDCDAM('DCDAMSVC','STRT')

回復対象外DAMファイル使用の終了

dc_dam_end

CBLDCDAM('DCDAMSVC','END ')

物理ファイルの割り当て

dc_dam_create

CBLDCDMB('DCDAMINT','CRAT')

物理ファイルのオープン

dc_dam_iopen

CBLDCDMB('DCDAMINT','OPEN')

物理ファイルからブロックの入力

dc_dam_get

CBLDCDMB('DCDAMINT','GET ')

物理ファイルへブロックの出力

dc_dam_put

CBLDCDMB('DCDAMINT','PUT ')

物理ファイルのブロックの検索

dc_dam_bseek

CBLDCDMB('DCDAMINT','BSEK')

物理ファイルからブロックの直接入力

dc_dam_dget

CBLDCDMB('DCDAMINT','DGET')

物理ファイルへブロックの直接出力

dc_dam_dput

CBLDCDMB('DCDAMINT','DPUT')

物理ファイルのクローズ

dc_dam_iclose

CBLDCDMB('DCDAMINT','CLOS')

TAMファイルサービス

TAMテーブルのオープン※

dc_tam_open

−

TAMテーブルからレコードの入力

dc_tam_read

CBLDCTAM('FxxR')('FxxU')('VxxR')('VxxU')

TAMテーブルのレコード入力を前提の更新

dc_tam_rewrite

CBLDCTAM('MFY ')('MFYS')('STR ')('WFY ') ('WFYS')('YTR ')

TAMテーブルのレコードの更新／追加

dc_tam_write

TAMテーブルのレコードの削除

dc_tam_delete

CBLDCTAM('ERS ')('ERSR')('BRS ')('BRSR')

TAMテーブルのレコードの入力取り消し※

dc_tam_read_cancel

−

TAMテーブルの状態の取得

dc_tam_get_inf

CBLDCTAM('GST ')

TAMテーブルの情報の取得

dc_tam_status

CBLDCTAM('INFO')

TAMテーブルのクローズ※

dc_tam_close

−

ISTサービス

ISTテーブルのオープン

dc_ist_open

CBLDCIST('DCISTSVC','OPEN')

ISTテーブルからレコードの入力

dc_ist_read

CBLDCIST('DCISTSVC','READ')

ISTテーブルへレコードの出力

dc_ist_write

CBLDCIST('DCISTSVC','WRIT')

ISTテーブルのクローズ

dc_ist_close

CBLDCIST('DCISTSVC','CLOS')

資源の排他制御

資源の排他

dc_lck_get

CBLDCLCK('GET ')

全資源の排他の解除

dc_lck_release_all

CBLDCLCK('RELALL ')

資源名称を指定した排他の解除

dc_lck_release_byname

CBLDCLCK('RELNAME ')

（凡例）

−：該当しません。

注※

COBOL-UAP作成用プログラムは使えません。

表1‒4　OpenTP1のライブラリ関数の一覧（X/Openに準拠した関数）

機能

ライブラリ関数名

C言語ライブラリ

COBOL-UAP作成用プログラム

XATMIインタフェース

リクエスト／レスポンス型サービスの呼び出しと応答の受信

tpcall()

TPCALL

リクエスト／レスポンス型サービスの呼び出し

tpacall()

TPACALL

リクエスト／レスポンス型サービスからの非同期応答の受信

tpgetrply()

TPGETRPLY

リクエスト／レスポンス型サービスのキャンセル

tpcancel()

TPCANCEL

会話型サービスとのコネクションの確立

tpconnect()

TPCONNECT

会話型サービスとのコネクションの切断

tpdiscon()

TPDISCON

会話型サービスからのメッセージの受信

tprecv()

TPRECV

会話型サービスへのメッセージの送信

tpsend()

TPSEND

型付きバッファの割り当て

tpalloc()

−

型付きバッファの解放

tpfree()

−

型付きバッファのサイズの変更

tprealloc()

−

型付きバッファの情報の取得

tptypes()

−

サービス名の広告

tpadvertise()

TPADVERTISE

サービス名の広告の取り消し

tpunadvertise()

TPUNADVERTISE

サービス関数のテンプレート

tpservice()

TPSVCSTART

サービス関数からのリターン

tpreturn()

TPRETURN

TXインタフェース

トランザクションの開始

tx_begin()

TXBEGIN

トランザクションのコミット

tx_commit()

TXCOMMIT

現在のトランザクションに関する情報の返却

tx_info()

TXINFORM

リソースマネジャ集合のオープン

tx_open()

TXOPEN

トランザクションのロールバック

tx_rollback()

TXROLLBACK

リソースマネジャ集合のクローズ

tx_close()

TXCLOSE

commit_return特性の設定

tx_set_commit_return()

TXSETCOMMITRET

transaction_control特性の設定

tx_set_transaction_control()

TXSETTRANCTL

transaction_timeout特性の設定

tx_set_transaction_timeout()

TXSETTIMEOUT

（凡例）

−：この機能に該当するXATMIインタフェースのCOBOLのAPIはありません。

表1‒5　OpenTP1のライブラリ関数の一覧（特殊な形態で使う関数）

機能

ライブラリ関数名

C言語ライブラリ

COBOL-UAP作成用プログラム

マルチノード機能※

OpenTP1ノードのステータス取得の開始

dc_adm_get_nd_status_begin

−

OpenTP1ノードのステータスの取得

dc_adm_get_nd_status_next

−

指定したOpenTP1ノードのステータスの取得

dc_adm_get_nd_status

−

OpenTP1ノードのステータス取得の終了

dc_adm_get_nd_status_done

−

ノード識別子の取得の開始

dc_adm_get_nodeconf_begin

−

ノード識別子の取得

dc_adm_get_nodeconf_next

−

ノード識別子の取得の終了

dc_adm_get_nodeconf_done

−

指定したノード識別子の取得

dc_adm_get_node_id

−

ユーザサーバのステータス取得の開始

dc_adm_get_sv_status_begin

−

ユーザサーバのステータスの取得

dc_adm_get_sv_status_next

−

指定したユーザサーバのステータスの取得

dc_adm_get_sv_status

−

ユーザサーバのステータス取得の終了

dc_adm_get_sv_status_done

−

オンラインテスタの管理

ユーザサーバのテスト状態の報告

dc_uto_test_status

CBLDCUTO('T-STATUS')

（凡例）

−：該当しません。

注※

マルチノード機能では，COBOL-UAP作成用プログラムは使えません。

(2)　アプリケーションプログラムで使えるライブラリ関数

OpenTP1のUAPで使えるライブラリ関数を表1-6〜表1-10に示します。ここでは，SUP，SPP，MHP，およびオフラインの業務をするUAPについて示します。

表1‒6　UAPで使えるライブラリ関数（OpenTP1の基本機能の関数）

OpenTP1のライブラリ関数名

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

dc_rpc_open

○

−

○M

−

−

○M

−

−

dc_rpc_mainloop

−

−

○M

−

−

−

−

−

dc_rpc_call

○

○

○

○

○

○

○

−

dc_rpc_call_to

○

○

○

○

○

○

○

−

dc_rpc_poll_any_replies

○

○

○

○

○

○

○

−

dc_rpc_get_error_descriptor

○

○

○

○

○

○

○

−

dc_rpc_discard_further_replies

○

○

○

○

○

○

○

−

dc_rpc_discard_specific_reply

○

○

○

○

○

○

○

−

dc_rpc_service_retry

−

−

○

−

−

○

−

−

dc_rpc_set_service_prio

○

○

○

○

○

○

○

−

dc_rpc_get_service_prio

○

○

○

○

○

○

○

−

dc_rpc_get_watch_time

○

○

○

○

○

○

○

−

dc_rpc_set_watch_time

○

○

○

○

○

○

○

−

dc_rpc_get_callers_address

−

−

○

○

○

−

−

−

dc_rpc_get_gateway_address

−

−

○

○

○

−

−

−

dc_rpc_cltsend

○

○

○

○

○

○

○

−

dc_rpc_close

○

−

○M

−

−

○M

−

−

dc_rap_connect

○

−

○

−

−

○

−

−

dc_rap_disconnect

○

−

○

−

−

○

−

−

dc_trn_begin※

○

−

○

−

−

○M

−

−

dc_trn_chained_commit※

−

○

−

○

−

−

−

−

dc_trn_chained_rollback※

−

○

−

○

−

−

−

−

dc_trn_unchained_commit※

−

○

−

○

−

−

○M

−

dc_trn_unchained_rollback※

−

○

−

○

○

−

○M

−

dc_trn_info

○

○

○

○

○

○

○

−

dc_trn_rm_select

○

−

○

−

−

−

−

−

dc_adm_call_command

○

○

○

○

○

○

○

−

dc_adm_complete

○

−

−

−

−

−

−

−

dc_adm_status

○

○

○

○

○

○

○

−

dc_log_audit_print

○

○

○

○

○

○

○

−

dc_logprint

○

○

○

○

○

○

○

−

dc_jnl_ujput※

−

○

−

○

○

−

○

−

CBLDCJUP('CLOSERPT')

−

−

−

−

−

−

−

○

CBLDCJUP('OPENRPT ')

−

−

−

−

−

−

−

○

CBLDCJUP('RDGETRPT')

−

−

−

−

−

−

−

○

dc_prf_utrace_put

○

○

○

○

○

○

○

○

dc_prf_get_trace_num

○

○

○

○

○

○

○

○

dc_rts_utrace_put

○

○

○

○

○

○

○

−

（凡例）

○：該当する条件で使えます。

○M：メイン関数からだけ，関数を使えます。

−：該当する条件では使えません。

注

MHPの「トランザクション処理の範囲でない」とは，非トランザクション属性のMHP，またはMHPのメイン関数の範囲を示します。

注※

この関数を使うUAPは，トランザクションとして実行する指定をしてください。

・TP1/Server Baseの場合：ユーザサービス定義でatomic_updateオペランドにYを指定

・TP1/LiNKの場合：アプリケーションプログラムの環境を設定するときに，トランザクション機能を使う指定

表1‒7　UAPで使えるライブラリ関数（TP1/Message Controlの関数）

OpenTP1のライブラリ関数名

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

dc_mcf_open

−

−

○M

−

−

○M

○M

−

dc_mcf_mainloop

−

−

−

−

−

○M

−

−

dc_mcf_receive

−

−

−

−

−

○NO

○

−

dc_mcf_reply

−

−

−

−

−

○NO

○

−

dc_mcf_send

−

−

−

○

○

○NO

○

−

dc_mcf_resend

−

−

−

○

○

−

○

−

dc_mcf_recvsync

−

−

○

○

○

○

○

−

dc_mcf_sendsync

−

−

○

○

○

○

○

−

dc_mcf_sendrecv

−

−

○

○

○

○

○

−

dc_mcf_tempget

−

−

−

−

−

○NO

○

−

dc_mcf_tempput

−

−

−

−

−

○NO

○

−

dc_mcf_contend

−

−

−

−

−

○NO

○

−

dc_mcf_execap

−

−

−

○

○

○NO

○

−

dc_mcf_ap_info

−

−

−

−

−

○NO

○

−

dc_mcf_ap_info_uoc

−

−

−

−

−

○NO

○

−

dc_mcf_timer_set

−

−

○

○

○

○

○

−

dc_mcf_timer_cancel

−

−

○

○

○

○

○

−

dc_mcf_commit

−

−

−

−

−

−

○

−

dc_mcf_rollback

−

−

−

−

−

−

○

−

dc_mcf_close

−

−

○M

−

−

○M

○M

−

dc_mcf_tlscom

−

−

○

○

○

○

○

−

dc_mcf_tlscn

−

−

○

○

○

○

○

−

dc_mcf_tactcn

−

−

○

○

○

○

○

−

dc_mcf_tdctcn

−

−

○

○

○

○

○

−

dc_mcf_tlsln

−

−

○

○

○

○

○

−

dc_mcf_tonln

−

−

○

○

○

○

○

−

dc_mcf_tofln

−

−

○

○

○

○

○

−

dc_mcf_adltap

−

−

○

○

○

○

○

−

dc_mcf_tlsle

−

−

○

○

○

○

○

−

dc_mcf_tdctle

−

−

○

○

○

○

○

−

dc_mcf_tactle

−

−

○

○

○

○

○

−

dc_mcf_tdlqle

−

−

○

○

○

○

○

−

（凡例）

○：該当する条件で使えます。

○M：メイン関数からだけ，関数を使えます。

○NO：非トランザクション属性のMHPのサービス関数の範囲でだけ，関数を使えます。

−：該当する条件では使えません。

注

MHPの「トランザクション処理の範囲でない」とは，非トランザクション属性のMHP，またはMHPのメイン関数の範囲を示します。

表1‒8　UAPで使えるライブラリ関数（ユーザデータを操作する関数）

OpenTP1のライブラリ関数名

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

dc_dam_open※

○

○

○

○

○

○

○

−

dc_dam_read※

○

○

○

○

○

○

○

−

dc_dam_rewrite※

（○）

○

（○）

○

○

（○）

○

−

dc_dam_write※

（○）

○

（○）

○

○

（○）

○

−

dc_dam_close※

○

○

○

○

○

○

○

−

dc_dam_hold

○

○

○

○

○

−

○

−

dc_dam_release

○

○

○

○

○

−

○

−

dc_dam_status

○

○

○

○

○

○

○

−

dc_dam_start

○

○

○

○

○

○

○

−

dc_dam_end

○

○

○

○

○

○

○

−

dc_dam_create

−

−

−

−

−

−

−

○

dc_dam_iopen

−

−

−

−

−

−

−

○

dc_dam_get

−

−

−

−

−

−

−

○

dc_dam_put

−

−

−

−

−

−

−

○

dc_dam_bseek

−

−

−

−

−

−

−

○

dc_dam_dget

−

−

−

−

−

−

−

○

dc_dam_dput

−

−

−

−

−

−

−

○

dc_dam_iclose

−

−

−

−

−

−

−

○

dc_tam_open

○

○

○

○

○

○

○

−

dc_tam_read

−

○

−

○

○

−

○

−

dc_tam_rewrite

−

○

−

○

○

−

○

−

dc_tam_write

−

○

−

○

○

−

○

−

dc_tam_delete

−

○

−

○

○

−

○

−

dc_tam_read_cancel

−

○

−

○

○

−

○

−

dc_tam_get_inf

○

○

○

○

○

○

○

−

dc_tam_status

○

○

○

○

○

○

○

−

dc_tam_close

○

○

○

○

○

○

○

−

dc_ist_open

○

○

○

○

○

○

○

−

dc_ist_read

○

○

○

○

○

○

○

−

dc_ist_write

○

○

○

○

○

○

○

−

dc_ist_close

○

○

○

○

○

○

○

−

dc_lck_get※

−

○

−

○

○

−

○

−

dc_lck_release_all※

−

○

−

○

○

−

○

−

dc_lck_release_byname※

−

○

−

○

○

−

○

−

（凡例）

○：該当する条件で使えます。

（○）：回復対象外のDAMファイルのときだけ使えます。

−：該当する条件では使えません。

注

MHPの「トランザクション処理の範囲でない」とは，非トランザクション属性のMHP，またはMHPのメイン関数の範囲を示します。

注※

この関数を使うUAPは，TP1/Server Baseの場合，トランザクション属性の指定（ユーザサービス定義でatomic_updateオペランドにYを指定）してください。ただし，回復対象外のDAMファイルへアクセスする場合はトランザクション処理を前提としません。

TP1/LiNKのUAPでは，これらの関数は使えません。

表1‒9　UAPで使えるライブラリ関数（X/Openに準拠した関数）

OpenTP1のライブラリ関数名

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

tpcall

○

○

○

○

○

−

−

−

tpacall

○

○

○

○

○

−

−

−

tpgetrply

○

○

○

○

○

−

−

−

tpcancel

○

○

○

○

○

−

−

−

tpconnect

○

○

○

○

○

−

−

−

tpdiscon

○

○

○

○

○

−

−

−

tprecv

○

○

○

○

○

−

−

−

tpsend

○

○

○

○

○

−

−

−

tpalloc

○

○

○

○

○

−

−

−

tpfree

○

○

○

○

○

−

−

−

tprealloc

○

○

○

○

○

−

−

−

tptypes

○

○

○

○

○

−

−

−

tpadvertise

−

−

○※1

○※1

○※1

−

−

−

tpunadvertise

−

−

○※1

○※1

○※1

−

−

−

tpservice※2

−

−

−

−

−

−

−

−

tpreturn

−

−

○※3

○※3

○※3

−

−

−

tx_begin※4

○

−

○

−

−

○

−

−

tx_commit

TX_CHAINED指定※4

−

○

○

−

−

−

−

−

tx_commit

TX_UNCHAINED指定※4

−

○

○

−

−

−

−

−

tx_info

○

○

○

○

○

−

−

−

tx_open

○

−

○

−

−

−

−

−

tx_rollback

TX_CHAINED指定※4

−

○

−

○

−

−

−

−

tx_rollback

TX_UNCHAINED指定※4

−

○

−

○

○

−

−

−

tx_close

○

−

○

−

−

−

−

−

tx_set_commit_return※4

○

○

○

○

○

−

−

−

tx_set_transaction

_control※4

○

○

○

○

○

−

−

−

tx_set_transaction

_timeout※4

○

○

○

○

○

−

−

−

（凡例）

○：該当する条件で使えます。

−：該当する条件では使えません。

注※1

この関数は，サービス関数の中でだけ使えます。

注※2

tpserviceは，サービス関数の実体です。

注※3

この関数は，XATMIインタフェースのサービス関数をリターンするためだけに使います。

注※4

この関数を使うUAPは，トランザクションとして実行する指定をしてください。

・TP1/Server Baseの場合：ユーザサービス定義でatomic_updateオペランドにYを指定

・TP1/LiNKの場合：アプリケーションプログラムの環境を設定するときに，トランザクション機能を使う指定

表1‒10　UAPで使えるライブラリ関数（特殊な形態で使う関数）

OpenTP1のライブラリ関数名

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

dc_adm_get_nd_status

_begin※

○

○

○

○

○

○

○

−

dc_adm_get_nd_status

_next※

○

○

○

○

○

○

○

−

dc_adm_get_nd_status※

○

○

○

○

○

○

○

−

dc_adm_get_nd_status

_done※

○

○

○

○

○

○

○

−

dc_adm_get_nodeconf

_begin※

○

○

○

○

○

○

○

−

dc_adm_get_nodeconf

_next※

○

○

○

○

○

○

○

−

dc_adm_get_nodeconf

_done※

○

○

○

○

○

○

○

−

dc_adm_get_node_id※

○

○

○

○

○

○

○

−

dc_adm_get_sv_status

_begin

○

○

○

○

○

○

○

−

dc_adm_get_sv_status

_next

○

○

○

○

○

○

○

−

dc_adm_get_sv_status

○

○

○

○

○

○

○

−

dc_adm_get_sv_status

_done

○

○

○

○

○

○

○

−

dc_uto_test_status

○

○

○

○

○

○

○

−

（凡例）

○：該当する条件で使えます。

−：該当する条件では使えません。

注※

この関数を使うUAPがあるノードには，TP1/Multiが組み込まれていることが前提です。

1.5　アプリケーションプログラムのデバッグとテスタ

OpenTP1では，作成したUAPを業務に使う前に，動作確認のテストができます。UAPをテストする機能をUAPテスタ機能といいます。

UAPテスタ機能を使うと，業務に使っている資源をテストのために変更する必要がなくなります。また，UAPテスタ機能はオペレータがコマンドを入力して確認する形式でテストできるため，テストしたい項目を重点的に確認できます。

1.5.1　UAPテスタ機能の種類

OpenTP1のUAPテスタ機能には，使う目的別に，次のものがあります。

(1)　オフラインテスタ（TP1/Offline Tester）

オンライン業務用のUAPをオフライン環境でテストする機能です。OpenTP1を稼働させていなくても，UAPの動作をテストできます。OpenTP1の資源を使う前に，UAPを単体でテストする場合に使います。オフラインテスタでは，高級言語（C言語，COBOL言語）のデバッガと連動できるので，テストとデバッグでUAPを二重にチェックできます。

オフラインテスタでは，SPPとMHPの動作をテストできます。

オフラインテスタを実行するマシンには，TP1/Offline Testerを組み込んであることが前提となります。

(2)　オンラインテスタ（TP1/Online Tester）

オンライン環境でUAPをテストする機能です。OpenTP1のシステムサービスと連携して，UAPの動作をテストできます。OpenTP1のUAPを統合してテストするときに使います。オンラインテスタでは，高級言語（C言語，COBOL言語）のデバッガと連動できるので，テストとデバッグでUAPを二重にチェックできます。

オンラインテスタでは，SUPとSPPの動作をテストできます。さらに，MHPをSPPとして動作をテストできます。

オンラインテスタを実行するマシンには，TP1/Online Testerを組み込んであることが前提となります。

(3)　MCFオンラインテスタ（TP1/Message Control/Tester）

オンライン環境でUAPをテストする機能です。TP1/Message Controlと連携して，MHPをテストするときに使います。OpenTP1のシステムサービスとMCFのシステムサービスを使って，UAPをテストできます。

MCFオンラインテスタを実行するマシンには，TP1/Message Control/Testerを組み込んであることが前提となります。また，オンラインテスタのUAPトレース機能を使う場合は，TP1/Online Testerを組み込んであることが前提となります。

1.5.2　テストできるアプリケーションプログラム

UAPテスタ機能でテストできるのは，SUP，SPP，およびMHPです。UAPテスタ機能によって，テストできる内容は異なります。

OpenTP1クライアント機能（TP1/Client）で使うUAP（CUP）では，CUPからサービスを要求したSPPをテストモードで起動できます。

オフラインの業務をするUAPは，UAPテスタ機能でテストできません。

UAPテスタ機能については，マニュアル「OpenTP1 テスタ・UAPトレース使用の手引」を参照してください。

1.5.3　ユーザサーバのテスト状態の報告

OpenTP1でオンラインテスタ（TP1/Online Tester）を使っている場合，ユーザサーバから状態を検知できます。テスト状態を検知するときは，dc_uto_test_status関数【CBLDCUTO('T-STATUS')】を使います。dc_uto_test_status関数でわかる項目を次に示します。

テストユーザID（環境変数DCUTOKEYに設定した値）

ユーザサーバがテストモードで稼働しているかどうか

グローバルトランザクションの処理状態

ユーザサービス定義に指定した，次の項目

test_modeオペランドに指定したテスト種別

test_transaction_commitオペランドで指定したトランザクションの同期点の扱い

test_adm_call_commandオペランドで指定したコマンドの実行結果の扱い

2　OpenTP1の基本機能（TP1/Server Base，TP1/LiNK）

TP1/Server Base，またはTP1/LiNKを使っているノードで使うアプリケーションプログラムの機能について説明します。

この章では，各機能をC言語の関数名で説明します。C言語の関数名に対応するCOBOL言語のAPIは，関数を最初に説明する個所に【 】で囲んで表記します。それ以降は，C言語の関数名に統一して説明します。COBOL言語のAPIがない関数の場合は，【 】の表記はしません。

2.1　リモートプロシジャコール

OpenTP1のUAPでは，サービスを提供するUAPがネットワークのどのノードにあるかを意識しなくても，UAPのサービスを関数呼び出しのように要求できます。このようなプロセス間通信をリモートプロシジャコール（RPC）といいます。OpenTP1のUAPで使えるリモートプロシジャコールには，次に示す3種類があります。

OpenTP1独自のインタフェース

XATMIインタフェース（X/Openの仕様に準拠したRPC）

TxRPCインタフェース（X/Openの仕様に準拠したRPC）

通信プロトコルにTCP/IPを使う場合には，上記3種類のリモートプロシジャコールを使えます。通信プロトコルにOSI TPを使う場合には，XATMIインタフェースだけを使えます。OSI TPを使う場合のリモートプロシジャコールについては，「2.10　OSI TPを使ったクライアント／サーバ形態の通信」および「5.1　XATMIインタフェース（クライアント／サーバ形態の通信）」を参照してください。

ここでは，OpenTP1独自のインタフェースのRPCについて説明します。XATMIインタフェースについては「5.1　XATMIインタフェース（クライアント／サーバ形態の通信）」を，TxRPCインタフェースについては「6.1　TxRPCインタフェースの通信」を参照してください。

注意事項

システム共通定義のall_nodeオペランドで指定したドメイン以外のOpenTP1システムにトランザクショナルRPCを行う場合，自ドメインおよび他ドメイン内のすべてのOpenTP1システムのノード識別子(システム共通定義のnode_idオペランド)は一意にする必要があります。また，すべてのOpenTP1システムは，バージョン03-02以降にする必要があります。これらの条件を満たしていないと，トランザクションが正しく回復できなくなる場合があります。

2.1.1　リモートプロシジャコールの実現方法

クライアントUAPから，サービスを要求する関数を使ってSPPのサービスを要求できます。UAPからサービスを要求するときは，サーバUAPのサービスグループ名※とサービス名を引数に設定したdc_rpc_call関数【CBLDCRPC('CALL ')】を呼び出します。要求されるサービスが，クライアントUAPと別のノードにあっても同じノードにあってもかまいません。要求されるサービスがどのノードにあるかは，OpenTP1のネームサービスで管理しているので，UAPで意識する必要はありません。

注※

サービスグループ名をドメイン修飾して設定することで，設定したドメイン内のサーバUAPへサービスを要求することもできます。ドメイン修飾したサービス要求については，「2.1.18　ドメイン修飾をしたサービス要求」を参照してください。

OpenTP1では，サーバUAPはサービス提供プログラム（SPP）です。SPPのサービスを要求できるクライアントUAPは，SUP，SPP，MHP，CUPです。

サーバUAPは，OpenTP1の開始と一緒に開始（自動起動）しておくか，OpenTP1の開始後にdcsvstartコマンドで開始（手動起動）しておきます。開始しておくことで，サーバUAPはサービスを提供できる状態になります。開始していないサーバUAPにサービスを要求すると，dc_rpc_call関数はエラーリターンします。

クライアントUAPは，開始したサーバUAPのプロセスが稼働しているかどうかに関係なく，dc_rpc_call関数でサービスを要求できます。サービスを要求したときに，指定したサーバUAPのプロセスが稼働していなくても，OpenTP1が自動的にプロセスを起動します。

MHPからRPCでサービスは要求できますが，MHPのサービス関数へはサービスを要求できません。また，オフラインの業務をするUAPでは，RPCを使えません。

RPCを使った通信のクライアント／サーバの関係を次の図に示します。

図2‒1　RPCを使った通信のクライアント／サーバの関係

2.1.2　リモートプロシジャコールでのデータの受け渡し

クライアントUAPからサービスを要求するときには，dc_rpc_call関数の引数に入力パラメタ，入力パラメタ長，応答を格納する領域，応答を受け取る領域の長さを設定します。

サービス関数では，応答を格納する領域に応答を，応答を受け取る領域の長さに応答の長さを設定してクライアントUAPに返します。

リモートプロシジャコールのデータの受け渡しを次の図に示します。

図2‒2　リモートプロシジャコールのデータの受け渡し

2.1.3　リモートプロシジャコールの形態

RPCには次の形態があります。RPCの形態は，クライアントUAPのdc_rpc_call関数にフラグで設定します。RPCの形態を次の図に示します。

図2‒3　RPCの形態

応答型RPC

サーバUAPの処理結果をクライアントUAPに返すRPCです。応答型RPCには，dc_rpc_call関数を呼び出してから，サーバUAPの処理結果が返ってくるのを待つ同期応答型RPCと，処理結果を非同期に受信する非同期応答型RPCがあります。

非応答型RPC

サーバUAPの処理結果をクライアントUAPに返さないRPCです。dc_rpc_call関数の呼び出し後にリターンして，処理を続けます。クライアントUAPではサーバUAPの処理結果を受信できません。

トランザクション処理でRPCを使った場合の，同期点とRPCとの関係については，「2.3.4　リモートプロシジャコールの形態と同期点の関係」を参照してください。

(1)　同期応答型RPC

dc_rpc_call関数を呼び出してから，サーバUAPの処理結果が返ってくるのを待つ形態です。同期応答型のRPCを使うときは，dc_rpc_call関数のflagsにDCNOFLAGS（またはDCRPC_CHAINED）を設定します。

(a)　同期応答型RPCの時間監視

dc_rpc_call関数を呼び出してから，応答が返るまでの時間は，次に示す値で監視されています。

TP1/Server Baseの場合：

ユーザサービス定義のwatch_timeオペランドに指定した値

TP1/LiNKの場合：

180秒

サーバUAPの処理に時間が掛かって，指定した監視時間を過ぎてしまった場合は，dc_rpc_call関数はエラーリターンします。

このときサーバUAPでは，クライアントUAPの応答待ち時間を認識しているため，クライアントUAPがタイムアウトしたあとにスケジューリングされたサービスは実行しないで廃棄し，実行中のサービスについては応答を返さずに処理を打ち切ります。サーバUAPで，クライアントUAPのタイムアウトを検知したことによって，サービス要求を廃棄したことをメッセージ表示したい場合は，サーバUAPのユーザサービス定義のrpc_extend_functionオペランドに00000008を指定してください。

サーバUAPが異常終了すると，dc_rpc_call関数はすぐにエラーリターンします。ただし，次に示す場合には，指定した監視時間が過ぎてからエラーリターンします。

サーバUAPがあるノードのOpenTP1全体が異常終了した場合

サービス要求のデータがサーバUAPに届く前，またはサーバUAPの処理が完了してからクライアントUAPに結果が届く前に障害が起こった場合

同期応答型RPCを次の図に示します。

図2‒4　同期応答型RPC

(2)　非同期応答型RPC

dc_rpc_call関数を呼び出してから，サーバUAPの処理結果が返ってくるのを待たないで処理を続ける形態です。非同期応答型RPCを複数回呼び出すことで，RPCを並行処理できます。

非同期応答型RPCのdc_rpc_call関数（flagsにDCRPC_NOWAITを設定）は，サービス要求後にリターンします。UAPではリターン後に処理を続けます。

非同期応答型RPCは，サービス要求がサーバに受け付けられたことを確認しないでリターンします。一つのクライアントUAPから同じサービスグループに複数の非同期応答型RPCでサービスを要求した場合，サーバ側でこの要求順どおりにサービスを受け付けるとは限りません。

(a)　非同期応答型RPCの応答の受信

サーバUAPの処理結果は，dc_rpc_poll_any_replies関数【CBLDCRPC('POLLANYR')】を呼び出して，非同期に受信します。処理結果は，dc_rpc_poll_any_replies関数を使わないと受信できません。

非同期応答型RPCの応答を受信するときは，どの応答を受信するか特定できます。特定する場合は，非同期応答型RPCのサービス要求をしたdc_rpc_call関数がリターンしたときに返された正の整数（記述子）を，dc_rpc_poll_any_replies関数の引数に設定します。この設定をすると，記述子に該当する非同期応答型RPCの応答を受信します。

受信する応答を特定しない場合は，応答が戻ってきた順に受信します。応答を特定しない場合，dc_rpc_poll_any_replies関数が正常に終了すると，受信した非同期応答の記述子と同じ値をリターンします。

非同期応答型RPCのdc_rpc_call関数を呼び出した数よりも多くdc_rpc_poll_any_replies関数を呼び出した場合は，エラーリターンします。

サービス要求でエラーが起こった場合は，dc_rpc_poll_any_replies関数にエラーリターンします。

flagsにDCRPC_NOWAITを設定したdc_rpc_call関数を呼び出し，dc_rpc_call関数に対する応答を受信する前にトランザクション同期点処理をする関数を呼び出すと，そのあとに呼び出すdc_rpc_poll_any_replies関数は，DCRPCER_ALL_RECEIVEDでエラーリターンし，応答を受信できません。非同期応答型RPCの場合，トランザクション内で実行したかどうかに関係なく，該当するプロセスでのトランザクション同期点処理の実行前に応答を受信する必要があります。

(b)　非同期応答型RPCの時間監視

非同期応答型RPCの場合，ユーザサービス定義のwatch_timeに指定した値は参照されません。dc_rpc_poll_any_replies関数を呼び出してから，応答が返るまでの最大応答待ち時間は，引数timeoutに設定します。

サーバUAPの処理に時間が掛かって，設定した監視時間を過ぎてしまった場合は，dc_rpc_poll_any_replies関数はエラーリターンします。

サーバUAPが異常終了すると，dc_rpc_poll_any_replies関数はすぐにエラーリターンします。ただし，次に示す場合には，設定した監視時間が過ぎてからエラーリターンします。

サーバUAPがあるノードのOpenTP1全体が異常終了した場合

サービス要求のデータがサーバUAPに届く前，またはサーバUAPの処理が完了してからクライアントUAPに結果が届く前に障害が起こった場合

処理結果の非同期受信を次の図に示します。

図2‒5　非同期応答型RPC（処理結果の非同期受信）

(c)　処理結果の受信を拒否

非同期応答型RPCで，まだ返ってきていない応答をこれ以上受信しない場合は，処理結果の受信を拒否する関数（dc_rpc_discard_further_replies関数【CBLDCRPC('DISCARDF')】）を呼び出します。この関数を呼び出したあとに返ってきた応答は，受信されないで捨てられます。非同期応答型RPCの結果を受信しない場合は，必ず処理結果の受信を拒否する関数を呼び出してください。呼び出さないと，ほかの非同期応答型RPCのdc_rpc_poll_any_replies関数が，不要な応答を受信してしまうことがあります。

dc_rpc_discard_further_replies関数を使うのは次のような場合です。

応答待ち時間切れになったあと，次の処理に移る前に，結果を保持しておくバッファをすぐに解放したい場合

非同期応答型RPCを複数回呼び出して，そのうち最初の応答だけ必要な場合

また，非同期応答型RPCで，まだ返ってきていない応答の中で特定の応答だけを受信しない場合は，特定の処理結果の受信を拒否する関数（dc_rpc_discard_specific_reply関数【CBLDCRPC('DISCARDS' )】）を呼び出します。この関数を呼び出したあとに返ってきた応答の中で，指定された記述子と同じ記述子を持つ応答は受信されないで捨てられます。

処理結果の受信の拒否を次の図に示します。

図2‒6　非同期応答型RPC（処理結果の受信を拒否）

(d)　同期点との関係

非同期応答型RPCをトランザクション内で呼び出した場合，同期点処理したあとは非同期に応答を受信できません。同期点と非同期応答型RPCについては，「2.3.4　リモートプロシジャコールの形態と同期点の関係」を参照してください。

(3)　非応答型RPC

サーバUAPの処理結果をクライアントUAPに返さないRPCです。クライアントUAPではサーバUAPの処理結果を受信できません。

非応答型RPCの時間監視はしません。

非応答型RPCのdc_rpc_call関数（flagsにDCRPC_NOREPLYを設定）は，サービス要求後にリターンします。UAPではリターン後は処理を続けます。サーバUAPの処理結果は受信できません。

非応答型RPCは，サービス要求がサーバに受け付けられたことを確認しないでリターンします。このことによって，通信障害などでサービス要求が消失しても，クライアントUAPで認識することはできません。また，一つのクライアントUAPから同じサービスグループに複数の非応答型RPCでサービスを要求した場合，サーバ側でこの要求順どおりにサービスを受け付けるとは限りません。

非応答型RPCを次の図に示します。

図2‒7　非応答型RPC

2.1.4　サービスのネスト

クライアントUAPからサービス要求されたサーバUAPから，さらにサーバUAPを呼ぶことができます。このようなサーバUAPのネストによって，サービス処理を分散化・階層化できます。RPCのネスト例を次の図に示します。

図2‒8　RPCのネスト例

2.1.5　トランザクションの処理から非トランザクショナルRPCの発行

トランザクションの処理からサービスを要求した場合に，サービスを要求されたUAPがトランザクション属性のときは，トランザクションの処理となります。このようなサービス要求を，トランザクション処理としないこともできます（非トランザクショナルRPC）。トランザクション処理としたくない場合は，dc_rpc_call関数の引数にトランザクションでないRPCであることを指定します。

トランザクション属性については，「2.3.3　トランザクション属性の指定」を参照してください。

2.1.6　サービス要求のスケジュールプライオリティの設定

一つの処理から呼び出す複数のサービス要求に優先順位を付けたい場合，サービス要求ごとのプライオリティを設定できます。dc_rpc_call関数を呼び出す直前に，

dc_rpc_set_service_prio関数【CBLDCRPC('SETSVPRI')】を呼び出してサービス要求のプライオリティを設定します。これによって，サービス要求の優先度が，サーバUAP側のスケジュールキューを経由してサーバに通知されます。

dc_rpc_set_service_prio関数を1度も使わない処理の場合は，スケジュールサービスの省略時解釈である4が，サービス要求のプライオリティとして指定されます。設定したスケジュールプライオリティは，dc_rpc_get_service_prio関数【CBLDCRPC('GETSVPRI')】で参照できます。

キュー受信型サーバ（スケジュールサービスでスケジュールされるSPP）では，設定したサービス要求のプライオリティは，サーバUAPのユーザサービス定義に，service_priority_controlオペランドにY（プライオリティを制御する）を指定している場合だけ有効です。サービスを要求する相手のサーバUAPでプライオリティを制御していない場合は，この関数を呼び出しても無効になります。

ソケット受信型サーバ（スケジュールキューを経由しないでサービス要求を受信するSPP）では，クライアントUAPで設定したプライオリティに無条件に従います。

次に示すサービス要求に対して，dc_rpc_set_service_prio関数を呼び出しても無効となります。

連鎖RPCの2回目以降のサービス要求

連鎖RPCを終了させるために呼び出す，同期応答型RPCのdc_rpc_call関数（flagsにDCNOFLAGSを設定）

2.1.7　クライアントUAPのノードアドレスの取得

クライアントUAPへのサービスを制限したい場合，サーバUAPでクライアントUAPを認識するため，クライアントUAPのプロセスが稼働するノードアドレスを取得できます。クライアントUAPのノードアドレスは，dc_rpc_get_callers_address関数【CBLDCRPC('GETCLADR')】で取得します。

dc_rpc_get_callers_address関数で返されたアドレスを使って，サービスの応答やエラーの応答などは送信できません。

dc_rpc_get_callers_address関数は，サービス関数から呼び出してください。サービス関数以外から呼び出した場合の処理は保証しません。

2.1.8　サービス要求の応答待ち時間の参照と更新

UAPの処理の中で，サービス要求の応答待ち時間を一時的に変更できます。現在の応答待ち時間の設定を参照するときはdc_rpc_get_watch_time関数【CBLDCRPC('GETWATCH')】を，変更するときはdc_rpc_set_watch_time関数【CBLDCRPC('SETWATCH')】を使います。dc_rpc_set_watch_time関数で変更した値は，該当のUAPでdc_rpc_close関数を呼び出すまで有効です。

dc_rpc_get_watch_time関数は，dc_rpc_set_watch_time関数で変更したサービス応答待ち時間をリターンします。応答待ち時間を変更していない場合は，次に示す値がリターンされます。

TP1/Server Baseの場合：

ユーザサービス定義のwatch_timeに指定した値

TP1/LiNKの場合 ：

180秒

この関数で得られる値は，OpenTP1のdc_rpc_call関数の応答待ち時間として有効です。

サービス要求の応答待ち時間を，dc_rpc_set_watch_time関数を呼び出す前の値に戻すときは，事前に呼び出しているdc_rpc_get_watch_time関数で返された元の値を，この関数で再設定してください。

dc_rpc_set_watch_time関数は，関数を呼び出したUAPのサービス要求に影響するだけで，システム共通定義のwatch_timeオペランドに指定した値は変更しません。この関数で設定する値は，あとから呼び出すdc_rpc_call関数にだけ影響します。

2.1.9　エラーが発生した非同期応答型RPC要求の記述子の取得

非同期応答を特定しないdc_rpc_poll_any_replies関数【CBLDCRPC('POLLANYR')】がエラーリターンした直後に呼び出すことで，エラーが発生した非同期応答型RPC要求に対応する記述子を取得できます。

エラーが発生した非同期応答型RPC要求に対応する記述子は，dc_rpc_get_error_descriptor関数【CBLDCRPC('GETERDES')】で取得します。

非同期応答の記述子を取得できるのは，SPP側でエラーが発生した場合だけです。

dc_rpc_poll_any_replies関数【CBLDCRPC('POLLANYR')】の呼び出し側でエラーが発生した場合には，dc_rpc_get_error_descriptor関数【CBLDCRPC('GETERDES')】で非同期応答の記述子を取得できません。

2.1.10　CUPへの一方通知

OpenTP1のサーバUAPから，TP1/Clientのアプリケーションプログラム（CUP）へUAPが開始したことを通知できます。CUPへは，dc_rpc_cltsend関数【CBLDCRPC('CLTSEND ')】でデータを送って，サーバUAPの開始を通知します。この機能を使って，サーバの起動完了を一斉にクライアントへ知らせることができます。

dc_rpc_cltsend関数で通知したデータは，CUPのdc_clt_chained_accept_notification関数またはdc_clt_accept_notification関数で受け取ります。CUPがデータを受け取ることで，TP1/Clientはサーバが稼働中であることがわかります。その後，CUPからサーバへサービスを要求します。

dc_rpc_cltsend関数は，通知する先のCUPがdc_clt_chained_accept_notification関数またはdc_clt_accept_notification関数で通知を待っているときにだけ使えます。CUPが稼働していない場合には，dc_rpc_cltsend関数はエラーリターンします。また，dc_rpc_cltsend関数でデータを通知できるのは，CUPのdc_clt_chained_accept_notification関数またはdc_clt_accept_notification関数だけです。そのほかのプロセス（サーバUAPのプロセス）へは，データを送信できません。dc_clt_chained_accept_notification関数またはdc_clt_accept_notification関数については，マニュアル「OpenTP1 クライアント使用の手引 TP1/Client/W，TP1/Client/P編」を参照してください。

CUPへの一方通知の概要を次の図に示します。

図2‒9　CUPへの一方通知の概要

2.1.11　リモートプロシジャコールとサービスを実行するプロセスの関連

サービスを要求されたサーバUAPは，クライアントUAPとは別のプロセスで実行されます。OpenTP1では，一つのサーバUAPを実行するためのプロセスを複数起動できるマルチサーバを実現できます。マルチサーバの場合でRPCをネストさせると，ネストさせるサービス数だけプロセスが実行される場合があります。

同じサーバUAPでも，クライアントUAPが異なれば，決まったプロセスで実行されるとは限りません。また，クライアントUAPと同じサービスグループに属するサービスを要求する場合でも，そのサービスグループを実行するための新しいプロセスが必要になります。マルチサーバを使う場合は，使用するプロセス数には余裕を持った値を指定しておいてください。

RPCとプロセスの関係を次の図に示します。

図2‒10　RPCとプロセスの関係

クライアントUAP1からサーバUAP1にサービスを要求した場合，サーバUAP1はプロセスAで実行されます。

クライアントUAP1からサーバUAP2にサービスを要求した場合，サーバUAP2はプロセスBで実行されます。

新たなクライアントUAP2からサーバUAP1にサービスを要求した場合，1.のサービス要求とは別の，プロセスCで実行されます。

(1)　連鎖RPC

同じサービスグループに属するサービスを2回以上要求する同期応答型RPCの場合に限り，そのサービスを以前と同じプロセスで実行できます。これを連鎖RPCといいます。連鎖RPCでサービスを要求すると，マルチサーバのサーバUAPでも前回のRPCと同じプロセスで実行されるため，トランザクション処理に必要なプロセスを最小限にできます。UAPのプロセスはサービスグループごとに確保されるため，同じサービスグループに属していれば，異なるサービスに対しても連鎖RPCでサービスを要求できます。

連鎖RPCの処理は，トランザクションとしてもトランザクションとしなくても実行できます。トランザクションとして連鎖RPCを実行する場合は，一つのグローバルトランザクションとして処理されます。

連鎖RPCは，クライアントUAPのプロセス単位で保証されます。ただし，同じグローバルトランザクション内でも，クライアントUAPが異なれば，複数回呼び出されたサービスは同じプロセスで起動されることは保証されません。

(a)　連鎖RPCの開始

連鎖RPCとなるサービス要求をする場合は，サービスを要求するdc_rpc_call関数のflagsにDCRPC_CHAINEDを設定してください。この値を設定してサービスを要求したことで，サーバUAP側は連鎖RPCであることを認識して，プロセスを確保します。2回目以降のサービス要求のflagsにも，DCRPC_CHAINEDを設定します。

2回目以降のサービス要求では，ユーザサーバおよびサービスの閉塞状態を検出できません。2回目以降のサービス要求の実行中に異常が発生した場合は，ユーザサーバが閉塞します。このとき，サービス単位には閉塞できません。

(b)　連鎖RPCの終了

連鎖RPCは，次のどれかの方法で終了します。

ユーザサービス定義のrpc_extend_functionオペランドに00000002を指定していない場合は，連鎖RPCを実行しているサービスグループに対して，同期応答型RPC（flagsにDCNOFLAGSを設定）でサービス要求する。

トランザクション実行中に開始した連鎖RPCの場合は，連鎖RPCを実行しているグローバルトランザクションを同期点処理（コミット，またはロールバック）で完了させる。

ユーザサービス定義のrpc_extend_functionオペランドに00000002を指定している場合は，トランザクション実行中に開始した非トランザクションの連鎖RPCが，同期点処理を実行したあと，連鎖RPCを実行しているサービスグループに対して同期応答型RPC（flagsにDCNOFLAGSを設定）でサービス要求する。

(c)　連鎖RPCの時間監視

連鎖RPCの処理中に通信障害などで次のサービス要求が受け取れないと，SPPがプロセスを確保したままになってしまうことがあります。これを防ぐため，連鎖RPCで実行しているSPPでは，応答を返してから次のサービス要求，または連鎖RPCの終了要求が来るまでの時間（最大時間間隔）を次に示す値で監視しています。

TP1/Server Baseの場合：

ユーザサービス定義のwatch_next_chain_timeオペランドに指定した値

TP1/LiNKの場合：

180秒

上記の監視時間を過ぎても次のサービス要求，または連鎖RPCの終了要求が来ない場合は，OpenTP1はクライアントUAPで障害が起こったものと見なして，該当するSPPのプロセスを異常終了させます。

(d)　ソケット受信型サーバへの連鎖RPCについて

ソケット受信型サーバ（スケジュールキューを経由しないでサービス要求を受信するSPP）は，マルチサーバとして稼働できません。また，非常駐プロセスとしても稼働できません。ソケット受信型サーバは，一つの常駐プロセスで稼働しています。

ソケット受信型サーバに対して連鎖RPCでのサービス要求をすると，サーバUAPは，該当のクライアントUAPだけからしかサービス要求を受け付けなくなります。ソケット受信型サーバへ連鎖RPCでのサービス要求は，できるだけしないようにしてください。

連鎖RPCとプロセスの関係を次の図に示します。

図2‒11　連鎖RPCとプロセスの関係

クライアントUAP1からサーバUAP1に連鎖RPC（flagsにDCRPC_CHAINEDを設定）でサービスを要求した場合，サーバUAP1はプロセスAで実行されます。

クライアントUAP1からサーバUAP2に連鎖RPCでサービスを要求した場合，サーバUAP2はプロセスBで実行されます。

クライアントUAP1からサーバUAP1に，再び連鎖RPCでサービスを要求した場合，1.のサービス要求と同じプロセスAで実行されます。

クライアントUAP1からサーバUAP1に，同期応答型RPC（flagsにDCNOFLAGSを設定）でサービスを要求した場合，サーバUAP1はプロセスAで実行されます。そしてクライアントUAP1とサーバUAP1の連鎖RPCは終了します。

クライアントUAP1からサーバUAP2に，連鎖RPCでサービスを要求した場合，サーバUAP2はプロセスBで実行されます。

同期点を取得すると，クライアントUAP1とサーバUAP2の連鎖RPCは終了します。

2.1.12　リカーシブコールを使うときの注意

実行中のサーバUAPから，自分と同じサービスグループ名とサービス名を指定してサービスを要求できます。これをリカーシブコール（再帰呼び出し）といいます。リカーシブコールの場合でも，その同じサービスを実行するために新しいプロセスが必要になります。そのため，リカーシブコールを使う場合，サービスを要求する指定をした時点で，実行できるプロセスがなくなる場合があります。このとき，RPCのタイムアウトになるか，待ち時間を指定していないときは永久に待ちになります。リカーシブコールを使うときは，余裕あるプロセス数を指定してください。なお，リカーシブコールを使えるのはキュー受信型サーバです。ソケット受信型サーバはリカーシブコールを使えません。

グローバルトランザクションの構成要素である一つのトランザクションブランチの中でも，リカーシブコールはできます。ただし，クライアントUAPと同じサービスグループに属していても，要求されたサービスは別プロセスで別のトランザクションブランチとして実行されます。

(1)　リカーシブコールとシステム定義との関連

ユーザサービス定義のbalance_countオペランドに設定した値によっては，リカーシブコールをしてもプロセスが増えないで，タイムアウトになる場合があります。次の場合には，必ずbalance_countオペランドの値に0を指定してください。

非常駐プロセスだけで構成されるユーザサーバでリカーシブコールをする場合（例えば，parallel_count=0,2の場合）。

一つの常駐プロセスと，ほかの非常駐プロセスで構成されるサーバでリカーシブコールをする場合（例えば，parallel_count=1,2の場合）。

ユーザサービス定義の最大プロセス数に1を指定した（parallel_count=1）のサービスグループに属するサービスでは，リカーシブコールは使えません。

2.1.13　サービス関数のリトライ

デッドロックなど，リトライすれば正常に実行できるトラブルが起こった場合に，クライアントUAPにエラーを返さないでサーバUAPのプロセスをリトライできます。サービス関数をリトライして，クライアントUAPからのサービス要求をやり直す手間を省きたいときに使います。

サービス関数をリトライする場合は，サービス関数でdc_rpc_service_retry関数【CBLDCRPC('SVRETRY ')】を呼び出します。その後サービス関数をリターンすると，同じプロセスで同じサービス関数が再起動されます。

サービス関数をリトライした場合は，リトライする前のサービス関数が設定した内容（応答を格納する領域と応答の長さ）は無効になります。

サービス関数をリトライする回数は，ユーザサービス定義のrpc_service_retry_countオペランドに指定します。このオペランドに指定した回数を超えた場合は，dc_rpc_service_retry関数はエラーリターンします。このあとにリターンしたサービス関数はリトライされないで，応答の領域に設定した内容をクライアントUAPに返します。

dc_rpc_service_retry関数を使う場合は，次に示す条件を満たしてください。この条件を満たさない場合は，関数がエラーリターンします。

サービス関数の中でdc_rpc_service_retry関数を呼び出していること。

実行中のサービス関数が，グローバルトランザクションの範囲でないこと。

サービス関数のリトライの概要を次の図に示します。

図2‒12　サービス関数のリトライの概要

2.1.14　ユーザデータの圧縮

ネットワーク上に送り出されるパケット数を削減し，ネットワークの負荷を軽減するため，RPCでやり取りするユーザデータを圧縮できます。ユーザデータを圧縮する場合は，クライアント側のOpenTP1のシステム共通定義のrpc_datacompオペランドにYを指定します。

(1)　データ圧縮機能

データ圧縮機能を使用すると，クライアント側のOpenTP1はクライアントUAPのサービス要求を圧縮してネットワーク上に送り出します。その要求に対し，SPPから返される応答もサーバ側のOpenTP1で圧縮されてネットワーク上に送り出されます。その応答を受け取ったクライアント側のOpenTP1は，圧縮データを復元してクライアントUAPに渡します。

rpc_datacompオペランドの指定は，dc_rpc_callでサービスを要求するクライアント側で有効になります。つまり，クライアント側のOpenTP1でrpc_datacompオペランドにYを指定していれば，サーバ側のOpenTP1にrpc_datacompオペランドにYが指定されていなくても，サービス要求メッセージも応答メッセージもユーザデータを圧縮してネットワークに送り出します。反対に，クライアント側のOpenTP1にrpc_datacompオペランドにYを指定していなければ，サーバ側のOpenTP1にrpc_datacompオペランドにYが指定されていても，サービス要求メッセージ・応答メッセージともにユーザデータを圧縮しません。ただし，サーバ側のOpenTP1がユーザデータの圧縮機能をサポートしている場合に限ります。

データ圧縮機能の概要を次の図に示します。

図2‒13　データ圧縮機能の概要

(2)　データ圧縮機能の効果

データ圧縮機能の効果は，ユーザデータの内容に依存します。ユーザデータ中に連続した同一文字が多く現れる場合は効果がありますが，同一文字が連続することのないユーザデータは圧縮の効果がありません。

クライアント側のOpenTP1でrpc_datacompオペランドにYを指定していても，ユーザデータに圧縮効果がないときは，圧縮しないでサービス要求を送信します。しかし，応答メッセージが圧縮効果のある場合は，応答のユーザデータは圧縮して返送します。なお，サービス要求を圧縮しない場合でも，応答を圧縮して返すのは，クライアント側・サーバ側ともにTP1/Server Baseのバージョンが03-06以降のときだけです。これ以外のバージョンでは，サービス要求を圧縮しない場合，応答は圧縮しないで返ります。

データ圧縮機能は，データ圧縮／復元のためのオーバヘッドがかかるため，事前にデータ圧縮による効果と性能への影響を評価してから使用してください。

2.1.15　サービス関数実行時間の監視

SPPのサービス関数開始から終了までの実行時間を監視できます。この機能はユーザ作成のサービス関数が，不具合によってダイナミックループしているような場合に，このサービスを打ち切るのに有効です。指定した監視時間を過ぎてもサービス関数がリターンしない場合，このSPPプロセスを強制終了させます。

サービス関数の実行時間を監視するにはユーザサービス定義のservice_expiration_timeオペランドに値を指定してください。

この機能は，SPPだけで動作し，MHPでは動作しません。また，OSI TPプロトコルを使用したXATMIインタフェースや，DCEプロトコルを使用したTxRPCインタフェースで稼働するSPPでは，この機能は動作しません。

サービス関数実行時間の監視の概要を次の図に示します。

図2‒14　サービス関数実行時間の監視の概要

2.1.16　マルチスケジューラ機能を使用したRPC

クライアントUAPが，他ノードのキュー受信型サーバ（スケジュールキューを使うSPP）に，マルチスケジューラ機能を使用してサービス要求することによって，一つのOpenTP1システムで，次の3方式のRPCを混在して使用できます。

通常のRPC

サービス要求先サーバが存在するOpenTP1システムの中から一つをランダムに選択し，そのOpenTP1システムのマスタスケジューラデーモンにサービス要求を送信する方式。

マルチプルポート指定RPC

サービス要求先サーバが存在するすべてのOpenTP1システムのマルチスケジューラデーモンの中から一つをランダムに選択し，サービス要求を送信する方式。

通信先を指定したRPC

dc_rpc_call_to関数の引数に指定したポート番号のマルチスケジューラデーモンにサービス要求を送信する方式。

マルチスケジューラ機能の詳細については，「1.3.6(9)　マルチスケジューラ機能」を参照してください。なお，この機能は，TP1/Extension 1をインストールしていることが前提です。TP1/Extension 1をインストールしていない場合の動作は保証できませんので，ご了承ください。

マルチスケジューラ機能を使用したRPCの概要を次の図に示します。

図2‒15　マルチスケジューラ機能を使用したRPCの概要

マルチスケジューラ機能を使用したサービス要求は，マルチスケジューラデーモンを起動しているノードにだけスケジュールします。ただし，サービス要求時に，指定したマルチスケジューラデーモンを起動しているOpenTP1システムが存在しない場合は，マスタスケジューラデーモンにサービス要求を送信します。

ポート番号を指定してサービス要求する際に，マルチスケジューラデーモンのポート番号を指定した場合，指定したマルチスケジューラデーモン経由でサービス要求をスケジューリングします。

マルチスケジューラデーモンがサービス要求を受信した際，サービス要求先ユーザサーバが閉塞していた場合や終了中であった場合は，マルチスケジューラ機能を使用するほかのノードのマルチスケジューラデーモンにサービス要求を送信します。ほかのノードに該当するマルチスケジューラデーモンが存在しない場合は，マスタスケジューラデーモンにサービス要求を送信します。

オンライン中にマルチスケジューラデーモンが異常終了した場合は，OpenTP1システムをダウンさせないで，異常終了したマルチスケジューラデーモンに該当するポート番号を割り当てて再起動します。ただし，再起動が2回失敗した場合は，OpenTP1システムをダウンさせます。

2.1.17　通信先を指定したRPC

dc_rpc_call関数を使ってサービスを要求する場合，要求するサービスがどこにあるかは，OpenTP1のネームサービスで管理しているので，クライアントUAPで意識する必要はありません。

これに対し，dc_rpc_call_to関数を使えば，特定のサービス要求先にサービスを要求できます。dc_rpc_call_to関数では，ドメイン修飾をしてサービスを要求できません。それ以外は，dc_rpc_call関数の機能と変わりません。

なお，この関数は，TP1/Extension 1をインストールしていることが前提です。TP1/Extension 1をインストールしていない場合の動作は保証できませんので，ご了承ください。この関数は，TP1/Server管理下のC言語で作成したUAPでだけ呼び出せます。COBOL言語で作成したUAPでは使用できません。

サービス要求先を特定するには，dc_rpc_call_to関数の引数に次のどれかを指定する必要があります。

ホスト名指定

/etc/hostsファイル，またはDNSなどでIPアドレスとマッピングできるホスト名を指定して，サービス要求先ノードを特定します。

このとき，サービス要求先のシステム共通定義のname_portオペランドに指定した値と，サービス要求元（dc_rpc_call_to関数を呼び出した側）のname_portオペランドに指定した値が同じであることが前提です。

ノード識別子指定

システム共通定義のnode_idオペランドに指定されているノード識別子を指定して，サービス要求先のOpenTP1ノードを特定します。

指定したノード識別子に対応するサービス要求先のOpenTP1ノードのホスト名がグローバルドメイン※内にあることが前提です。

ホスト名とポート番号の指定

次の値を指定することでサービス要求先を特定します。

/etc/hostsファイル，またはDNSなどでIPアドレスとマッピングできるホスト名

上記で指定したホストにあるOpenTP1システムの，システム共通定義のname_portオペランドに指定したネームサービスのポート番号

このとき，サービス要求先のname_portオペランドに指定した値と，サービス要求元のname_portオペランドに指定した値は同じでなくてもまいません。

注※

ここでのグローバルドメインとは，次のノード名の集合を指します。

システム共通定義のname_domain_file_useオペランドにNを指定している場合

システム共通定義のall_nodeオペランド，all_node_exオペランドで指定したノード名の集合です。

システム共通定義のname_domain_file_useオペランドにYを指定している場合

ドメイン定義ファイルに指定したノード名の集合です。なお，ドメイン定義ファイルの格納場所は次のとおりです。

all_nodeのドメイン定義ファイル

$DCCONFPATH/dcnamndディレクトリ下

all_node_exのドメイン定義ファイル

$DCCONFPATH/dcnamndexディレクトリ下

ノード識別子を指定して，サービス要求先を特定したdc_rpc_call_to関数を使った通信の例を次の図に示します。

図2‒16　dc_rpc_call_to関数を使った通信の例

2.1.18　ドメイン修飾をしたサービス要求

サービスを要求すると，OpenTP1はシステムを構成するネットワークすべてを対象にして，通信相手を探します。そのため，ネットワークが大規模になると，サービス要求のスケジューリングに時間が掛かってしまいます。これを解決するため，ネットワークをDNSのドメインごとに区切ってサービスを要求できます。ドメインごとに区切ってサービスを要求すると，そのドメイン内で通信相手を探すため，スケジュールの性能が上がります。

ドメイン修飾をするときには，DNSのドメイン名を使います。このドメイン名をdc_rpc_call関数の引数のサービスグループ名に続けて設定します。ドメイン修飾をしてサービスを要求する方法については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編にあるdc_rpc_call関数の説明を参照してください。

(1)　ドメイン修飾をするサービス要求の前提条件

ドメイン修飾をする場合の前提条件を次に示します。

ドメイン代表スケジュールサービスを起動するホスト名を，namdomainsetupコマンドで，DNSへ登録してあること。

ドメイン代表スケジュールサービスを起動するOpenTP1のスケジュールサービス定義のscd_portオペランドに，スケジュールサービスのポート番号を指定してあること。

ドメイン修飾をしてサービスを要求するOpenTP1を起動するホストの/etc/servicesに，2.で指定したスケジュールサービスのポート番号が登録してあること。

(2)　ドメイン修飾をするサービス要求の制限

ドメイン修飾をしたサービス要求では，通常のサービス要求に比べて，次の制限があります。

キュー受信型サーバのサービスだけ，要求できます。ソケット受信型サーバのサービスは，ドメイン修飾をして要求できません。

トランザクション処理からサービスを要求しても，要求されたサービスの処理はトランザクションブランチにはなりません。

ドメイン修飾をしたサービス要求の概要を次の図に示します。

図2‒17　ドメイン修飾をしたサービス要求の概要

2.1.19　サービス関数とスタブの関係

SPPまたはMHPでサービス関数を作成する方法は，次の二つです。

スタブを使用して，該当するサービス関数を作成する方法

サービス関数動的ローディング機能を使用して，サービス関数を作成する方法

ここでは，上記の二つの方法について説明します。

(1)　スタブを使用する場合

RPCを使ってUAP間で通信するときには，スタブが必要です。スタブとは，クライアントUAPが指定した「サービスグループ名＋サービス名」とサーバUAPのサービスとを対応づけるプログラムです。

スタブではUAPの各サービスの入り口点（エントリポイント）を指定します。

エントリポイント名とは，C言語の関数名であり，COBOL言語のプログラム名または入り口名のことです。

サービス名とエントリポイント名は，1対1で対応させてください。複数のサービス名に1つのエントリポイント名を対応させることはできません。

サービス名とエントリポイント名は，ユーザサービス定義で指定しているserviceオペランドの名称と合わせてください。

スタブはサーバUAPの作成時に，サーバUAPのオブジェクトファイルと結合させます。

クライアント専用のUAPであるSUPと，オフラインの業務をするUAPには，スタブを定義して結合させる必要はありません。

スタブを使用してサービス関数を作成する方法について，SPPの場合とMHPの場合に分けてそれぞれ以降の図に示します。

図2‒18　スタブを使用する場合（SPP）

RPCインタフェース定義にサービス関数のエントリポイントを指定して，スタブを生成するコマンドでスタブを生成します。

ユーザサービス定義では，サービスグループ名とサービス名を指定します。

実行時には，サービスを要求されたサーバUAPの実行形式ファイルでは，スタブとユーザサービス定義によって作成されたライブラリ部で，該当のサービスを検索します。その後サービスの処理をしてクライアントUAPに結果を返します。

図2‒19　スタブを使用する場合（MHP）

RPCインタフェース定義にサービス関数のエントリポイントを指定して，スタブを生成するコマンドでスタブを生成します。

MCFアプリケーション定義では，アプリケーション名，サービスグループ名，およびサービス名を対応づけます。ユーザサービス定義では，サービスグループ名とサービス名を指定します。

実行時には，TP1/Message Controlの処理によって，MCFアプリケーション定義に基づきアプリケーション名に対応するサービス名が検索され，該当するサーバUAPを起動します。サービスを要求されたサーバUAPの実行形式ファイルでは，スタブとユーザサービス定義によって作成されたライブラリ部で，該当のサービスを検索します。その後サービスの処理をし，処理の完了をTP1/Message Controlに通知します。

(2)　サービス関数動的ローディング機能を使用する場合

サービス関数動的ローディング機能を使う場合，UAPの各サービスの入り口点（エントリポイント）を指定したUAPライブラリからサービス関数を取得するため，スタブは不要です。その代わりに，サービス関数を共用ライブラリ化してUAP共用ライブラリ※を作成する必要があります。これによって，UAP共用ライブラリからサービス関数を取得できるとともに，複数のサービスをメイン関数にまとめる作業は不要になります。

注※

UAP共用ライブラリとは，UAPのソースファイルを翻訳（コンパイル）して作成したUAPオブジェクトファイルを結合（リンケージ）して，共用ライブラリとしてまとめたものです。

サービス関数動的ローディング機能を使用してサービス関数を作成する方法について，SPPの場合とMHPの場合に分けてそれぞれ以降の図に示します。

図2‒20　サービス関数動的ローディング機能だけを使用する場合（SPP）

図2‒21　サービス関数動的ローディング機能だけを使用する場合（MHP）

なお，サービス関数動的ローディング機能は，スタブを使ったUAPでも使用できます。この場合，スタブを使ったUAPを変更しないで，サービス関数を追加できます。

サービス関数動的ローディング機能とスタブを併用してサービス関数を作成する方法について，SPPの場合とMHPの場合に分けてそれぞれ以降の図に示します。

図2‒22　サービス関数動的ローディング機能とスタブを併用する場合（SPP）

図2‒23　サービス関数動的ローディング機能とスタブを併用する場合（MHP）

2.2　リモートAPI機能

OpenTP1では，クライアント側のノードにあるUAPが発行したAPIを，OpenTP1がサーバ側に転送してサーバ側のプロセスで実行できます。このような機能をリモートAPI機能といいます。リモートAPI機能を要求するクライアント側のノードにあるUAPをrapクライアントといいます。rapクライアントが発行したAPIを，OpenTP1のrapリスナーが受け付け，rapサーバがサーバ側のノードで実行します。rapリスナー，rapサーバはOpenTP1のユーザサービスとして動作します。ユーザはrapsetupコマンドでrapリスナーとrapサーバの動作環境を設定してください。

リモートAPI機能を使用するユーザは，通信相手のサービス情報（ホスト名とポート番号）を，ユーザサービスネットワーク定義に-wオプション付きで定義しておきます。また，サーバ側にrapリスナーサービス定義を作成し，rapdfgenコマンドでrapリスナー用ユーザサービス定義とrapサーバ用ユーザサービス定義を自動生成します。リモートAPI機能を次の図に示します。

図2‒24　リモートAPI機能

次に，リモートAPI機能で代理実行できるAPIをrapクライアントの種類ごとに示します。

TP1/Server Base，TP1/LiNKがrapクライアントとなる場合

C言語ライブラリ

COBOL-UAP作成用プログラム

dc_rpc_call

CBLDCRPC('CALL ')

TP1/LiNKを使用する場合は，マニュアル「TP1/LiNK 使用の手引」を参照してください。

TP1/Client/P，TP1/Client/Wがrapクライアントとなる場合

C言語ライブラリ

COBOL-UAP作成用プログラム

dc_rpc_call_s

CBLDCRPS（'CALL '）

dc_trn_begin_s

CBLDCTRS（'BEGIN '）

dc_trn_chained_commit_s

CBLDCTRS（'C-COMMIT'）

dc_trn_chained_rollback_s

CBLDCTRS（'C-ROLL '）

dc_trn_unchained_commit_s

CBLDCTRS（'U-COMMIT'）

dc_trn_unchained_rollback_s

CBLDCTRS（'U-ROLL '）

TP1/Client/PおよびTP1/Client/Wを使用する場合は，マニュアル「OpenTP1 クライアント使用の手引 TP1/Client/W，TP1/Client/P編」を参照してください。

TP1/Client/Jがrapクライアントとなる場合

メソッド

rpcCall

trnBegin

trnChainedCommit

trnChainedRollback

TrnUnchainedCommit

trnUnchainedRollback

TP1/Client/J編を使用する場合は，マニュアル「OpenTP1 クライアント使用の手引 TP1/Client/J編」を参照してください。

TP1/Client for .NET Frameworkがrapクライアントとなる場合

メソッド

Call

Begin

CommitChained

RollbackChained

Commit

Rollback

TP1/Client for .NET Frameworkを使用する場合は，マニュアル「TP1/Client for .NET Framework 使用の手引」を参照してください。

2.2.1　リモートAPI機能の使用例

リモートAPI機能を使うと，ファイアウォールの内側にあるUAPに対してもサービスを要求できます。ファイアウォールの内側へのRPCを次の図に示します。

図2‒25　ファイアウォールの内側にあるUAPへのリモートプロシジャコール

2.2.2　常設コネクション

OpenTP1は，リモートAPIを要求したUAP（rapクライアント）とrapサーバとの間に，論理的な通信路（常設コネクション）を設定します。

常設コネクションのスケジュール方法には，スタティックコネクションスケジュールモードとダイナミックコネクションスケジュールモードがあります。どちらを使用するかは，rapリスナーサービス定義のrap_connection_assign_typeオペランドで指定できます。

2.2.3　コネクトモード

常設コネクションの管理方法は，コネクションの確立・解放方法によって二つに分けられます。コネクションの確立，解放をOpenTP1が管理する形態をオートコネクトモード，ユーザが管理する形態を非オートコネクトモードといいます。ユーザは常設コネクションをオートコネクトモードで管理するか，非オートコネクトモードで管理するか，rapクライアントのユーザサービス定義で定義します。

(1)　オートコネクトモード

OpenTP1が常設コネクションの確立・解放を管理する形態です。rapクライアントが，ユーザサービスネットワーク定義に-wオプション付きで定義されているサービスグループ名を指定してdc_rpc_call関数を発行した場合に，自動的に常設コネクションを確立します。

ユーザサービスネットワーク定義に定義されているサービスグループにdc_rpc_call関数を発行した時点から，dc_rpc_close関数を発行してRPCを終了するまで常設コネクションを確保します。

オートコネクトモードの概要を次の図に示します。

図2‒26　オートコネクトモードの概要

rapクライアントはrapサーバとの間で設定するコネクション数に上限があり，dc_rpc_call関数の呼び出し時にこのコネクション数の上限を超える場合は，rapクライアントプロセスで使用しているコネクションの中で，最も以前に使われたコネクションを自動的に解放したあと，新たにコネクションを確立します。

ただし，連鎖RPCを実行中のコネクションは，解放の対象とはなりません。このことが原因で解放できるコネクションがない場合は，APIを発行したUAPはダウンします。

(2)　非オートコネクトモード

ユーザが常設コネクションの確立・解放を管理する形態です。ユーザはrapクライアントでコネクションを確立するためにdc_rap_connect関数【CBLDCRAP('CONNECT ')】を発行し，解放するためにdc_rap_disconnect関数【CBLDCRAP('DISCNCT ')】を発行します。rapクライアントが，ユーザサービスネットワーク定義に-wオプション付きで定義されているサービスグループ名を指定してdc_rpc_call関数を発行したときに，ユーザが常設コネクションを確立していない場合，dc_rpc_call関数はエラーリターンします。リターンコードはDCRPCER_PROTOです。

非オートコネクトモードの概要を次の図に示します。

図2‒27　非オートコネクトモードの概要

dc_rap_connect関数発行時に，rapクライアントはrapサーバとの間で設定するコネクション数の上限を超える場合，エラーリターンします。

2.2.4　常設コネクションでの連鎖RPC

ここでは，常設コネクションでの連鎖RPCとして，オートコネクトモードでの連鎖RPC，および非オートコネクトモードでの連鎖RPCについて説明します。

(1)　オートコネクトモードでの連鎖RPC

rapクライアントはrapサーバとの間で設定するコネクション数に上限があり，dc_rpc_call関数の呼び出し時にこのコネクション数の上限を超える場合は，rapクライアントプロセスで使用しているコネクションの中で，最も以前に使われたコネクションを自動的に解放したあと，新たにコネクションを確立します。

ただし，連鎖RPCを実行中のコネクションは，解放の対象とはなりません。このことが原因で解放できるコネクションがない場合は，APIを発行したUAPはダウンします。

(2)　非オートコネクトモードでの連鎖RPC

連鎖RPC実行中にdc_rap_disconnect関数が呼び出されたり，APIを発行したUAPのダウンや通信障害が発生した場合，APIを代理実行中のrapサーバは，連鎖RPCを実行しているSPPとのコネクションやステータスをリセットするために，いったん異常終了し，再起動します。

2.2.5　注意事項

リモートAPI機能を利用する場合は，次の点に注意してください。

非同期応答型RPCを使用してはいけません。非同期応答型RPCを使用した場合，リモートAPI機能として動作しないで，通常のRPCとして動作します。

リモートAPI機能では，XATMIインタフェースを使用してはいけません。XATMIインタフェースを使用した場合，OpenTP1の動作は保証されません。

トランザクション内から，リモートAPI機能を使ってdc_rpc_callを発行しても，トランザクションとして処理されません。

リモートAPI機能による通信はRPCトレースに取得されません。ただし，rapサーバで代理実行したdc_rpc_callはRPCトレースに取得されます。

レスポンス統計情報，および通信遅延時間統計情報には，リモートAPI機能による通信部分は取得されません。

アプリケーションゲートウェイ型ファイアウォールの，ゲートウェイを介してRPCを実行する場合などで，ユーザサービスネットワーク定義のdcsvgdef定義コマンドに-wオプションを指定してリモートAPI機能を使用するときは，トランザクション属性でdc_rpc_call関数を呼び出してもトランザクションにはなりません。そのため，リモートAPI機能を使用した場合，トランザクション内から連鎖RPCを開始して，同期点処理で連鎖RPCを終了させる運用は正しく動作しません。flagsにDCNOFLAGSを指定したdc_rpc_call関数を呼び出して，明示的に連鎖RPCを終了してください。

通常，rapサーバはrapリスナーによって自動的に開始されます。rapサーバを単独で終了（dcsvstopコマンド実行）または開始（dcsvstartコマンド実行）しないでください。ただし，次の場合は，dcsvstartコマンドでrapサーバを開始してください。

定義エラーなどが原因で，rapサーバの開始に失敗した場合

定義エラーなどが原因でrapサーバを開始できない場合でも，rapリスナーはrapサーバを開始できないことを検知できません。そのため，システムは，リモートAPIサービスの準備中（KFCA26950-Iメッセージが出力された状態）のままになってしまいます。rapリスナーによるrapサーバの開始時に，要因コードがCONFIGURATIONのKFCA01812-Eメッセージが出力された場合は，rapサーバの定義を見直し，dcsvstartコマンドでrapサーバを開始してください。なお，rapサーバの定義エラーは，KFCA00244-Eメッセージでは検出できません。

rapリスナーおよびrapサーバの終了中にrapリスナーがダウンした場合

rapリスナーのダウン後に，dcsvstartコマンドでrapリスナーを開始しても，rapサーバがKFCA26950-Iメッセージを出力し，リモートAPIサービスの準備中のままになることがあります。rapサーバが開始されないときは，dcsvstartコマンドでrapサーバを開始してください。

rapサーバのオンライン中に，rapサーバに対してscdholdコマンドを実行しないでください。

rapサーバと同一のノードにあるUAPに対して，リモートAPI機能を使用したサービス要求をしないでください。サービス要求をした場合の動作は保証しません。

非オートコネクトモードで，コネクション確立後に発行したdc_rpc_callがエラーとなった場合は，dc_rap_disconnectでコネクションを解放したあと，再度dc_rap_connectでコネクションを確立させてください。

2.3　トランザクション制御

OpenTP1では，クライアント／サーバ形態の通信のトランザクション制御ができます。これによって，複数のプロセスにわたるUAPの処理を一つのトランザクションとして処理できます。OpenTP1のUAPで使えるトランザクション制御の関数には，次に示す2種類があります。

OpenTP1独自のインタフェース

TXインタフェース（X/Openの仕様に準拠したトランザクション制御）

ここでは，OpenTP1独自のインタフェースについて説明します。TXインタフェースについては，「5.2　TXインタフェース（トランザクション制御）」を参照してください。

ここでは，クライアント／サーバ形態のUAP（SUP，SPP）のトランザクション制御について説明します。メッセージ送受信形態のUAP（MHP）のトランザクション制御については，「3.7　MCFのトランザクション制御」を参照してください。

TP1/LiNKの場合の注意

TP1/LiNKで使うUAPでトランザクション制御をする場合は，TP1/LiNKの実行環境を設定するときに，トランザクション機能を使う指定をしてください。

2.3.1　クライアント／サーバ形態の通信のトランザクション

OpenTP1では，RPCを使用して複数のUAPプロセスにわたっている処理を，1件のトランザクション処理にできます。このようなトランザクションをグローバルトランザクションといいます。このグローバルトランザクションによって，クライアント／サーバ形態のトランザクションができるようになります。

(1)　トランザクションの開始と同期点の取得

クライアント／サーバ形態の通信でトランザクションを制御するときは，トランザクションの開始と同期点の取得をUAPで明示します。

トランザクションを開始するときは，次に示す関数を呼び出します。

dc_trn_begin関数【CBLDCTRN('BEGIN ')】

同期点を取得するときは，次に示す関数を呼び出します。

dc_trn_chained_commit関数【CBLDCTRN('C-COMMIT')】

dc_trn_chained_rollback関数【CBLDCTRN('C-ROLL ')】

dc_trn_unchained_commit関数【CBLDCTRN('U-COMMIT')】

dc_trn_unchained_rollback関数【CBLDCTRN('U-ROLL ')】

トランザクションを開始した時点で，クライアントUAPはルートトランザクションブランチになります。トランザクションの同期点取得（コミット）は，トランザクションを開始したルートトランザクションブランチで呼び出します。

トランザクションを開始したあとに，そのグローバルトランザクションの中で新しいトランザクションは開始できません。

トランザクションとして実行中のUAPから要求されたサービスは，要求された時点ですでにトランザクションとして実行しています。このとき，要求されたサービスの処理からdc_trn_begin関数は呼び出せません。

(2)　トランザクションを制御する関数を使えるUAP

トランザクションの開始，または同期点を取得する関数を呼び出せるのは，SUPとSPPです。MHPのトランザクション処理はOpenTP1で自動的に制御しているので，MHPからトランザクションを制御する関数は呼び出せません。また，MHPからdc_rpc_call関数でサービスを要求されるSPPでも，トランザクションを制御する関数は呼び出せません。

オフラインの業務をするUAPでは，トランザクションを制御する関数を使えません。

OpenTP1クライアント機能のUAP（CUP）は，TP1/Clientのライブラリにあるトランザクション制御の関数を使います。

2.3.2　同期点の取得

グローバルトランザクションを構成するトランザクションブランチのすべてを，同期を取って同じ決着結果（コミットまたはロールバック）で終了させることを同期点の取得といいます。

(1)　コミットの関数の呼び出し

UAPからコミットを指示する関数は，ルートトランザクションブランチ（dc_trn_begin関数でトランザクションを開始したSPPまたはSUP）からだけ使えます。ルートトランザクションブランチ以外のトランザクションブランチでは，コミットの関数は使えません。グローバルトランザクションは，すべてのトランザクションブランチが正常に終了したことで正常終了となります。

(a)　連鎖／非連鎖モードのコミット

トランザクション処理の同期点を取得する関数には，一つのトランザクションの終了後，同期点を取得して次のトランザクションを続けて起動する連鎖モードのコミット（dc_trn_chained_commit関数）と，トランザクションの終了で同期点を取得したあとに，新たなトランザクションを起動しない非連鎖モードのコミット（dc_trn_unchained_commit関数）があります。

トランザクションの連鎖／非連鎖モードを次の図に示します。

図2‒28　トランザクションの連鎖／非連鎖モード

(2)　ロールバックの関数の呼び出し

トランザクションをUAPの判断でロールバックとしたいときは，UAPからロールバックを要求できます。

(a)　連鎖／非連鎖モードのロールバック

ロールバックの関数には，連鎖モードのロールバック（dc_trn_chained_rollback関数）と非連鎖モードのロールバック（dc_trn_unchained_rollback関数）があります。連鎖モードのロールバックの場合は，ロールバック処理後も新しいグローバルトランザクションの範囲にあります。非連鎖モードのロールバックをルートトランザクションブランチから呼び出した場合は，グローバルトランザクションの範囲にはありません。

連鎖モードのロールバックは，ルートトランザクションブランチからしか呼び出せません。非連鎖モードのロールバックは，どのトランザクションブランチからでも呼び出せます。

ルート以外のトランザクションブランチから非連鎖モードのロールバックを呼び出した場合は，そのトランザクションブランチがロールバック対象である（rollback_only状態）ことをルートトランザクションブランチに通知します。この場合，ロールバック関数のあとから，dc_rpc_call関数がリターンするまでの処理もグローバルトランザクションの範囲にあります。

トランザクションのロールバックを次の図に示します。

図2‒29　トランザクションのロールバック

(3)　同期点を取得する処理でエラーが起こった場合

トランザクションの同期点を取得する処理でエラーが起こった場合，そのトランザクションが同期点の1相目まで完了していればコミットして，1相目まで完了していなければロールバックします。グローバルトランザクション内のどれか一つのトランザクションブランチがロールバックになった場合は，グローバルトランザクション全体がロールバックになります。

同期点を取得する処理でエラーが起こった場合のロールバックを次の図に示します。

図2‒30　同期点を取得する処理でエラーが起こった場合のロールバック

(4)　同期点を取得する関数を呼び出さなかった場合の処理

同期点を取得する関数を呼び出す前にUAPが異常終了した場合は，UAPの同期点の決着結果はロールバックになります。

同期点を取得する関数を呼び出さないで，ルートトランザクションブランチのUAPがexit()した場合は，OpenTP1が自動的にコミットの処理をします。そのコミット処理で1相目が完了する前にエラーが起こった場合は，グローバルトランザクションはロールバックされます。この場合，UAPには通知できません。

2.3.3　トランザクション属性の指定

UAPの実行環境を設定するときには，UAPのプロセスをトランザクションとして稼働させるかどうかを指定しておきます。トランザクションとして稼働する指定をしたUAPプロセスを，トランザクション属性のUAPといいます。ファイルの更新など，トランザクション処理をするUAPには，トランザクション属性である指定をしておく必要があります。

(1)　UAPをトランザクション属性とする方法

サーバUAPのプロセスをトランザクションブランチとしたい場合は，トランザクション属性のUAPであることを指定します。トランザクション属性を指定する方法を次に示します。

TP1/Server Baseの場合：

ユーザサービス定義のatomic_updateオペランドにYを指定

TP1/LiNKの場合：

ユーザサーバにトランザクション機能を使うことを指定

トランザクション属性を指定したUAPの処理がトランザクションとなるのは，次の場合です。

トランザクション属性を指定したUAPから，トランザクションの開始（dc_trn_begin関数）を呼び出して正常にリターンした場合

トランザクションとして処理しているほかのUAPから，dc_rpc_call関数でサービスを要求された場合

(2)　UAPをトランザクション属性なしとする場合

演算だけのサーバUAPなど，処理をトランザクションとして保証しなくてもよいサーバUAPには，トランザクション属性なし（atomic_updateオペランドにN，またはトランザクション機能を使わないと指定）にしておきます。トランザクション属性なしと指定したサーバUAPは，グローバルトランザクションの処理とは無関係に，いつでもほかのクライアントUAPにサービスを提供できます。そのため，複数のクライアントUAPからサービスを要求された場合でも，同期点を取得する処理が完了するのを待たないで並行して処理できて，サービス要求待ちのオーバヘッドを減らせます。

RPCとトランザクション属性の関係を次の図に示します。

図2‒31　RPCとトランザクション属性の関係

注※

グローバルトランザクションBでアクセスした資源の内容は，グローバルトランザクションBが開始する直前の状態に戻ります。グローバルトランザクションBがロールバックしたことは，同期点を取得する関数（この図の場合はdc_trn_unchained_commit関数）がエラーリターンすることで通知されます。

(a)　トランザクションの処理から非トランザクショナルRPCの発行

トランザクションの処理からサービスを要求した場合に，サービスを要求されたUAPがトランザクション属性のときは，トランザクションの処理となります。このようなサービス要求を，トランザクション処理としないこともできます。トランザクション処理としたくない場合は，dc_rpc_call関数の引数にトランザクションでないRPCであることを指定します。

2.3.4　リモートプロシジャコールの形態と同期点の関係

トランザクションとして稼働しているUAP（SUP，SPP，MHP）からRPCで呼ばれたSPPにトランザクション属性が指定してある場合は，そのSPPはトランザクションとして稼働します。各トランザクションブランチは，一つのグローバルトランザクションとして同期を取れます。したがって，各サーバUAPのプロセスは，処理終了後，dc_rpc_call関数を呼び出したUAPにリターンしても，ルートトランザクションブランチに戻って同期点処理が完了するまでは，次のサービス要求を受け付けられません。また，サーバUAPで確保している資源も解放されません。これは非同期応答型RPC，非応答型RPC，連鎖RPCの場合でも同様です。

このように，UAPの処理ではRPCのトランザクション制御で，複数のUAPで同期が取れます。

クライアントUAPの同期点処理が完了する前に，サーバUAPのプロセスでほかのサービス要求を処理できる場合があります。これをトランザクションの最適化といいます。トランザクションの最適化については，「2.3.5　トランザクションの最適化」を参照してください。

(1)　同期応答型RPCと同期点の関係

同期応答型RPCのトランザクション処理の場合は，ルートトランザクションブランチに処理結果が戻って，同期点処理を終えた時点でトランザクションの終了となります。

トランザクションを最適化する条件がそろっている場合，サーバUAPのプロセスは処理が終了した時点で，次のサービス要求を受け付けられます。

同期応答型RPCと同期点の関係を次の図に示します。

図2‒32　同期応答型RPCと同期点の関係

(2)　非同期応答型RPCと同期点の関係

非同期応答型RPCのトランザクション処理の場合は，クライアントUAPで同期点処理を終えた時点でRPCの処理を終了とします。同期点処理後にサーバUAPから応答が返ってきても，dc_rpc_call関数を呼び出したUAPでは受信できません。

非同期応答型RPCと同期点の関係を次の図に示します。

図2‒33　非同期応答型RPCと同期点の関係

(3)　非応答型RPCと同期点の関係

非応答型RPCのトランザクション処理の場合は，クライアントUAPの同期点取得でサーバUAPの処理終了を待って，そのあとで同期点処理をします。

非応答型RPCと同期点の関係を次の図に示します。

図2‒34　非応答型RPCと同期点の関係

(4)　連鎖RPCと同期点の関係

連鎖RPCを使った場合は，一つのサーバUAPのプロセスで実行します。したがって，トランザクションブランチも連鎖RPCを使った回数に関係なく，一つになります。

連鎖RPCのトランザクション処理の場合，同期点処理を終了した時点でトランザクションが終了して，処理していたサーバUAPのプロセスは解放されます。

トランザクション実行中に非トランザクションの連鎖RPCを使った場合，通常は同期点処理を終了した時点で，処理していたサーバUAPのプロセスを解放します。同期点処理の終了で処理していたサーバUAPのプロセスを解放しないで，同期応答型RPC（flagsにDCNOFLAGSを指定）で解放する場合は，ユーザサービス定義のrpc_extend_functionオペランドに00000002を指定してください。

同期応答型RPCで連鎖RPCを終了した場合，トランザクションを最適化する条件がそろっているときは，サーバUAPのプロセスは処理が終了した時点で，次のサービス要求を受け付けられます。

連鎖RPCと同期点の関係を以降の図に示します。

図2‒35　連鎖RPCと同期点の関係（トランザクションの連鎖RPC）

図2‒36　連鎖RPCと同期点の関係（非トランザクションの連鎖RPCで終了しない指定をした場合）

(5)　リモートプロシジャコールのエラーリターン値と同期点

dc_rpc_call関数，またはdc_rpc_poll_any_replies関数がエラーリターンしても，トランザクションの同期点がコミットとなる場合があります。

また，リターン値によっては，必ずトランザクションをロールバックさせなければならない場合があります。この場合は，ロールバックの関数（dc_trn_chained_rollback関数，またはdc_trn_unchained_rollback関数）でロールバックさせてください。

必ずロールバックさせなければならないdc_rpc_call関数，またはdc_rpc_poll_any_replies関数のリターン値については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編の説明を参照してください。

2.3.5　トランザクションの最適化

OpenTP1では，トランザクション処理の性能を上げるため，次のような最適化の処理をしています。

コミット最適化　1.

プリペア最適化　2.

非同期プリペア最適化　3.

1相最適化　4.

リードオンリー最適化　5.

ノーアクセス最適化　6.

ロールバック最適化　7.

それぞれの最適化には，最適化できる条件があります。条件を満たしたUAPを作成すると，トランザクション処理の性能を上げることができます。

最適化の優先順位を次に示します。

5.6.7.＞2.＞3.＞4.（1.はほかの最適化と同時に実行されます）

トランザクションの最適化は，クライアント側のトランザクションブランチとサーバ側のトランザクションブランチとの間で，同期点処理の効率を上げることを目的としています。そのため，一つのグローバルトランザクション内で複数の最適化を混在できます。

連鎖RPCを使うと，グローバルトランザクション内のトランザクションブランチの数が少なくなるので，トランザクションをより効率的に実行できます。

(1)　通常のトランザクション処理（2相コミット）

OpenTP1では，X/OpenのXAインタフェースによってトランザクションを制御しています。XAインタフェースでは，プリペア処理とコミット処理に分けて，トランザクションの同期点を取得しています。このような同期点処理を，2相コミットといいます。したがって，クライアントUAPとサーバUAPの間では，同期点処理要求の送信と確認の応答で，合計4回通信することになります。2相コミットの処理では，トランザクション処理のプロセスは同期点を取得するまで，次のサービス要求を受け取れません。

通常のトランザクション処理（2相コミット）の概要を，次の図に示します。

図2‒37　通常のトランザクション処理（2相コミット）の概要

(2)　コミット最適化

コミット最適化の条件を満たすと，サーバ側のトランザクションブランチで実行する同期点処理の2相目（コミット処理／ロールバック処理）を，クライアント側のトランザクションブランチで実行します。このことで，2回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，コミット最適化は無条件に実行されます。

クライアント側のトランザクションブランチと，サーバ側のトランザクションブランチが，同じOpenTP1システム内にある。

サーバ側のトランザクションブランチでアクセスしたリソースマネジャのXAインタフェースオブジェクトファイルが，クライアント側のトランザクションブランチにもリンケージされている。

コミット最適化をした場合，サーバ側のトランザクションブランチは，同期点処理の1相目が終了した時点で，2相目の完了を待たないで，次のサービス要求を受け付けられます。

コミット最適化の概要を次の図に示します。

図2‒38　コミット最適化の概要

(3)　プリペア最適化

プリペア最適化の条件を満たすと，サーバ側のトランザクションブランチで実行する同期点処理の1相目（プリペア処理）を，クライアント側のトランザクションブランチで実行します。このことで，2回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，プリペア最適化は無条件に実行されます。

クライアント側のトランザクションブランチと，サーバ側のトランザクションブランチが，同じOpenTP1システム内にある。

サーバ側のトランザクションブランチでアクセスしたリソースマネジャのXAインタフェースオブジェクトファイルが，クライアント側のトランザクションブランチにもリンケージされている。

クライアント側のトランザクションブランチは，同期応答型RPC（dc_rpc_call関数のflagsにDCNOFLAGSを設定）を使っている。

プリペア最適化をした場合は，コミット最適化も実行できるため，4回のプロセス間通信を削減できます。また，サーバ側のトランザクションブランチでは，同期点処理の完了を待たないで，次のサービス要求を受け付けられます。

プリペア最適化の概要を次の図に示します。

図2‒39　プリペア最適化の概要

(4)　非同期プリペア最適化

非同期プリペア最適化の条件を満たすと，サーバ側のトランザクションブランチがサービス処理が終了した時点で，クライアント側のトランザクションブランチへリターンする前に，プリペア処理を実行します。このことで，2回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，非同期プリペア最適化は実行されます。

クライアント側のUAPで，ユーザサービス定義のtrn_optimum_itemオペランドにasyncprepareを指定している。

プリペア最適化が実行できない条件であること（実行できる場合は，プリペア最適化が非同期プリペアよりも優先される）。

クライアント側のトランザクションブランチは，同期応答型RPC（dc_rpc_call関数のflagsにDCNOFLAGSを設定）を使っている。

非同期プリペア最適化をした場合，RPCの応答時間が通常のトランザクション処理よりも長くなります。また，クライアント側のトランザクションブランチのOpenTP1が，トランザクション処理中に異常終了した場合，ジャーナル取得の関係で，サーバ側のトランザクションブランチのOpenTP1も異常終了する場合があります。

非同期プリペア最適化の概要を次の図に示します。

図2‒40　非同期プリペア最適化の概要

(5)　1相最適化

1相最適化の条件を満たすと，クライアント側のトランザクションブランチがリソースマネジャへアクセスしないため，サーバ側のトランザクションブランチの同期点処理だけで済みます。このことで，2回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，1相最適化は実行されます。

クライアント側のトランザクションブランチにリンケージされているリソースマネジャは，動的登録をするリソースマネジャだけである。

クライアント側のトランザクションブランチは，リソースマネジャへのアクセスやユーザジャーナルの出力をしていない。

クライアント側のトランザクションブランチには，子トランザクションブランチが一つだけである。

1相最適化の概要を次の図に示します。

図2‒41　1相最適化の概要

(6)　リードオンリー最適化

リードオンリー最適化の条件を満たすと，サーバ側のトランザクションブランチが更新処理をしていない場合に，同期点処理の2相目を実行しません。このことで，2回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，リードオンリー最適化は実行されます。

サーバ側のトランザクションブランチは，リソースの更新処理（参照処理は除く），およびユーザジャーナルの出力をしていない。

クライアント側のトランザクションブランチには，子トランザクションブランチが一つだけである。

リードオンリー最適化をした場合，サーバ側のトランザクションブランチは，同期点処理の1相目が終了した時点で，2相目の完了を待たないで，次のサービス要求を受け付けられます。

リードオンリー最適化の概要を次の図に示します。

図2‒42　リードオンリー最適化の概要

(7)　ノーアクセス最適化

ノーアクセス最適化の条件を満たすと，サーバ側のトランザクションブランチがリソースマネジャへアクセスしていない場合，同期点処理をしません。このことで，4回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，ノーアクセス最適化は実行されます。

クライアント側のトランザクションブランチは，同期応答型RPC（dc_rpc_call関数のflagsにDCNOFLAGSを設定）を使っている。

サーバ側のトランザクションブランチにリンケージされているリソースマネジャは，動的登録をするリソースマネジャだけである。

サーバ側のトランザクションブランチは，リソースマネジャへのアクセス，およびユーザジャーナルへの出力をしていない。

サーバ側のトランザクションブランチには，子トランザクションブランチがない。または子トランザクションブランチが存在しても，その子トランザクションブランチはリードオンリー最適化ができる状態である。

ノーアクセス最適化をした場合，サーバ側のトランザクションブランチは，同期点処理の完了を待たないで，次のサービス要求を受け付けられます。

ノーアクセス最適化の概要を次の図に示します。

図2‒43　ノーアクセス最適化の概要

(8)　ロールバック最適化

ロールバック最適化の条件を満たすと，サーバ側のトランザクションブランチで，ロールバックの関数を使った場合，ほかのトランザクションブランチと同期を取らないでロールバックします。また，ほかのトランザクションブランチは同期点処理の1相目を実行しません。このことで，2回分のプロセス間通信が不要になって，トランザクション処理の性能が上がります。

次に示す条件をすべて満たした場合に，ロールバック最適化は実行されます。

クライアント側のトランザクションブランチは，同期応答型RPC（dc_rpc_call関数のflagsにDCNOFLAGSを設定）を使っている。

サーバ側のトランザクションブランチで，ロールバック関数を使っている。

ロールバック最適化をした場合，サーバ側のトランザクションブランチは，同期点処理の完了を待たないで，次のサービス要求を受け付けられます。

ロールバック最適化の概要を次の図に示します。

図2‒44　ロールバック最適化の概要

(9)　連鎖RPCを使った最適化

通常，トランザクションブランチからトランザクション属性を指定したUAPへサービスを要求すると，サーバ側のトランザクションブランチのプロセスは，別のトランザクションブランチとして実行されます。ただし，同じサービスグループ（同じサービスでなくても良い）へ連鎖RPC（dc_rpc_call関数のflagsにDCRPC_CHAINEDを設定）を使うと，その連鎖RPCを終了するまで一つのトランザクションブランチとして実行されます。連鎖RPCの条件を満たすと，グローバルトランザクション内のトランザクションブランチの数が削減されて，トランザクション処理の性能が上がります。

連鎖RPCを使った最適化の概要を次の図に示します。

図2‒45　連鎖RPCを使った最適化の概要

2.3.6　現在のトランザクションに関する情報を報告

UAPからdc_trn_info関数【CBLDCTRN('INFO ')】を呼び出すと，そのリターン値で，トランザクションとして稼働中かどうかを知ることができます。

2.3.7　ヒューリスティック発生時の処置

ノード間で通信障害が起こって，トランザクションブランチ間で連絡できなくなった場合，各ノードでコマンドを実行して同期点を取得する必要があります。各ノードで同期点を取得すると，グローバルトランザクションの中で，あるトランザクションブランチがコミット，あるトランザクションブランチがロールバックとなることがあります。このように，ノードごとに同期点を取得することをヒューリスティック決定といいます。ヒューリスティック決定の状態のときは，UAPでグローバルトランザクションの同期点を取得しようとすると，関数がエラーリターンします。ヒューリスティック決定が原因で，関数がエラーリターンする値を次に示します。

ヒューリスティック決定の結果が，グローバルトランザクションの同期点の結果と一致しなかった場合

DCTRNER_HEURISTIC（00903）

障害のため，ヒューリスティックに完了したトランザクションブランチの同期点の結果が判明しない場合

DCTRNER_HAZARD（00904）

このリターン値が戻る原因になったUAPやリソースマネジャ，およびグローバルトランザクションの同期点の結果は，メッセージログファイルの内容を参照して確認してください。

2.3.8　トランザクション処理での注意事項

(1)　ユーザサービス定義との関連

トランザクションとして実行中のサービスから，トランザクション属性であることを指定（atomic_updateオペランドにYを指定）したサービスを要求する場合は，次のことに気を付けてください。

サーバUAPのユーザサービス定義の最大プロセス数（parallel_countオペランド）は余裕を持った値を指定しておいてください。サーバUAPの処理が終了しても，グローバルトランザクションの同期点処理が完了するまで，ほかのクライアントUAPにはサービスを提供しません（ただし，同期点処理の最適化ができる場合を除きます）。この場合，トランザクションが長時間続くと，その間にサービスを要求した，異なるクライアントUAPの数だけのプロセスを占有することになります。そのため，トランザクションの性能が低下するおそれがあります。

ユーザサービス定義のサービス要求滞留値（balance_countオペランド）に指定した値によっては，マルチサーバ機能を使ったユーザサーバでも非常駐プロセスが増えないで，RPCがタイムアウトになる場合があります。balance_countオペランドには，サーバUAPの負荷に応じた最適な値を指定してください。

次の場合には，必ずbalance_countオペランドに0を指定してください。

非常駐プロセスだけで構成されるユーザサーバでリカーシブコールをする場合（例えば，parallel_count=0,2の場合）。

一つの常駐プロセスと，ほかの非常駐プロセスで構成されるユーザサーバでリカーシブコールをする場合（例えば，parallel_count=1,2の場合）。

(2)　トランザクション処理の時間監視について

トランザクションの開始から同期点処理までの時間監視では，トランザクション内で呼び出したdc_rpc_call関数がリターンするまでの時間を含めるか含めないかを選択できます。この指定はユーザサービス定義，ユーザサービスデフォルト定義，トランザクションサービス定義のtrn_expiration_time_suspendオペランドで指定します。

trn_expiration_time_suspendオペランドに指定する値とトランザクションの時間監視の詳細については，マニュアル「OpenTP1 システム定義」を参照してください。

2.4　システム運用の管理

ここでは，UAPから関数を呼び出してOpenTP1のコマンドを実行する方法，SUPの開始処理完了の報告，およびUAPから関数を呼び出してUAPの状態を取得する方法について説明します。

2.4.1　運用コマンドの実行

OpenTP1システムの運用を支援するために，オンライン中に入力できるOpenTP1のコマンドを，UAPからdc_adm_call_command関数【CBLDCADM('COMMAND ')】で実行できます。コマンドの実行結果は，UAPにリターンします。リターンする内容は標準出力，または標準エラー出力に出力される値です。

コマンドを実行するUAPには，次に示す指定をして，コマンドがあるディレクトリをコマンドのサーチパスに定義しておいてください。

TP1/Server Baseの場合：

ユーザサービス定義のputenv PATHに環境変数を指定

TP1/LiNKの場合：

TP1/LiNKの環境設定時にサーチパスを追加

dc_adm_call_command関数を使ったOpenTP1のコマンド実行の概要を次の図に示します。

図2‒46　dc_adm_call_command関数を使ったOpenTP1のコマンド実行の概要

(1)　dc_adm_call_command関数で実行できるOpenTP1のコマンド

OpenTP1のコマンドとUAPからの実行可否を次の表に示します。

表2‒1　OpenTP1のコマンドとUAPからの実行可否

機能

コマンド名

UAPから実行

システム管理

OpenTP1のOSへの登録と削除

dcsetup

×

プロセスサービスの再起動および定義の反映

dcreset

×

OpenTP1の内部制御用資源の確保と解放

dcmakeup

×

OpenTP1の開始

dcstart

×

OpenTP1の終了

dcstop

○※1

システム統計情報の取得開始，終了

dcstats

○

マルチノードエリア，サブエリアの開始

dcmstart

○

マルチノードエリア，サブエリアの終了

dcmstop

○

シナリオテンプレートからのOpenTP1コマンドの実行

dcjcmdex

×

システム定義のオペランドの指定

dcjchconf

×

ドメイン定義ファイルの更新

dcjnamch

○

OpenTP1ノードの状態表示

dcndls

○

共用メモリの状態表示

dcshmls

○

一時クローズ処理の実行状態の表示

rpcstat

○

標準出力，標準エラー出力のリダイレクト

prctee

×

prcteeプロセスの停止と再開始

prctctrl

×

保守資料の取得

dcrasget

○

システム統計情報の標準出力へのリアルタイム編集出力

dcreport

○

トラブルシュート情報の削除

dccspool

○

システム定義のチェック

dcdefchk

×

製品情報の表示

dcpplist

○

リモートAPI管理

rapリスナーおよびrapサーバの状態表示

rapls

×

リモートAPI機能の実行環境の設定

rapsetup

×

リモートAPI機能に使用する定義の自動生成

rapdfgen

×

サーバ管理

サーバの開始

dcsvstart

○

サーバの終了

dcsvstop

○

サーバの状態表示

prcls

○

ユーザサーバ，およびユーザサーバから起動されるコマンドのサーチパスの表示

prcpathls

○

ユーザサーバ，およびユーザサーバから起動されるコマンドのサーチパスの変更

prcpath

○※2

UAP共用ライブラリのサーチパスの表示

prcdlpathls

○

UAP共用ライブラリのサーチパスの変更

prcdlpath

○※2

OpenTP1のプロセスの強制停止

prckill

○

スケジュール管理

スケジュールの状態表示

scdls

○

スケジュールの閉塞

scdhold

○

スケジュールの再開始

scdrles

○

プロセス数の変更

scdchprc

○

プロセスの停止および再起動

scdrsprc

○

トランザクション管理

トランザクションの状態表示

trnls

○

トランザクションの強制コミット

trncmt

○

トランザクションの強制ロールバック

trnrbk

○

トランザクションの強制終了

trnfgt

○

トランザクション統計情報の取得開始，終了

trnstics

○

未決着トランザクション情報ファイルの削除

trndlinf

○

OSI TP通信の未決着トランザクション情報の表示

tptrnls

○

XAリソース管理

XARイベントトレース情報の表示

xarevtr

×

XARファイルの状態表示

xarfills

○

XARトランザクション状態の変更

xarforce

○

XAリソースサービスの閉塞

xarhold

○

XARファイルの作成

xarinit

×

XARトランザクション情報の表示

xarls

○

XAリソースサービスの閉塞解除

xarrles

○

XARファイルの削除

xarrm

×

排他管理

排他情報の表示

lckls

○

排他制御用テーブルのプール情報の表示

lckpool

○

デッドロック情報ファイルとタイムアウト情報ファイルの削除

lckrminf

○

ネーム管理

OpenTP1起動確認，キャッシュ削除

namalivechk

○

ドメイン代表スケジュールサービスの登録，削除

namdomainsetup

○

ドメイン構成の変更（システム共通定義使用）

namndchg

○

ドメイン構成の変更（ドメイン定義ファイル使用）

namchgfl

○

起動通知情報の強制的無効化

namunavl

×

OpenTP1のサーバ情報の表示

namsvinf

○

RPC抑止リストの操作

namblad

○

ノードリスト情報の削除（ノード自動追加機能使用時）

namndrm

×

マネジャノードの変更（ノード自動追加機能使用時）

nammstr

×

ノードリストファイルの作成（ノード自動追加機能使用時）

namnlcre

×

ノードリストファイルの内容表示（ノード自動追加機能使用時）

namnldsp

○

ノードリストファイルの削除（ノード自動追加機能使用時）

namnldel

×

ノードのオプション情報の変更（ノード自動追加機能使用時）

namndopt

○

メッセージログ管理

メッセージログファイルの内容表示

logcat

○

メッセージログのリアルタイム出力機能の切り替え

logcon

○

監査ログ

監査ログ機能の環境設定

dcauditsetup

×

OpenTP1ファイル管理

OpenTP1ファイルシステムの初期設定

filmkfs

×

OpenTP1ファイルシステムの状態表示

filstatfs

○

OpenTP1ファイルシステムの内容表示

fills

○

OpenTP1ファイルシステムのバックアップ

filbkup

×

OpenTP1ファイルシステムのリストア

filrstr

×

OpenTP1ファイルグループの変更

filchgrp

○

OpenTP1ファイルのアクセス許可モードの変更

filchmod

○

OpenTP1ファイル所有者の変更

filchown

○

ステータスファイル管理

ステータスファイルの作成，初期設定

stsinit

×

ステータスファイルの状態表示

stsls

○

ステータスファイルの内容表示

stsfills

○

ステータスファイルのオープン

stsopen

○

ステータスファイルのクローズ

stsclose

○

ステータスファイルの削除

stsrm

○

ステータスファイルのスワップ

stsswap

○

ジャーナル関係のファイル管理

ジャーナル関係のファイルの初期設定

jnlinit

×

ジャーナル関係のファイル情報の表示

jnlls

○

再開始中読み込み済ジャーナル関係のファイル情報の表示

jnlrinf

×

ジャーナル関係のファイルのオープン

jnlopnfg

○

ジャーナル関係のファイルのクローズ

jnlclsfg

○

ジャーナル関係の物理ファイルの割り当て

jnladdpf

○

ジャーナル関係の物理ファイルの削除

jnldelpf

○

ジャーナル関係のファイルのスワップ

jnlswpfg

○

ジャーナル関係のファイルの削除

jnlrm

×

ジャーナル関係のファイルのステータス変更

jnlchgfg

×

ジャーナル関係のファイルのアンロード

jnlunlfg

×

自動アンロード機能の制御

jnlatunl

×

ジャーナル関係のファイルの回復

jnlmkrf

×

ファイル回復用ジャーナルの集積

jnlcolc

×

アンロードジャーナルファイルの複写

jnlcopy

×

アーカイブ状態の表示

jnlarls

○

アンロードジャーナルファイル，またはグローバルアーカイブアンロードジャーナルファイルの編集出力

jnledit

×

アンロードジャーナルファイル，またはグローバルアーカイブアンロードジャーナルファイルのレコード出力

jnlrput

×

アンロードジャーナルファイル，およびグローバルアーカイブアンロードジャーナルファイルの時系列ソート，およびマージ

jnlsort

×

稼働統計情報の出力

jnlstts

×

MCF稼働統計情報の出力

jnlmcst

×

リソースグループの接続の強制解除

jnlardis

×

DAMファイル管理

物理ファイルの初期設定

damload

×

論理ファイルの状態表示

damls

○

論理ファイルの追加

damadd

○

論理ファイルの切り離し

damrm

○

論理ファイルの論理閉塞

damhold

○

論理ファイルの閉塞解除

damrles

○

物理ファイルの削除

damdel

×

物理ファイルのバックアップ

dambkup

×

物理ファイルのリストア

damrstr

×

論理ファイルの回復

damfrc

×

キャッシュブロック数のしきい値の設定

damchdef

○

キャッシュブロック数の取得

damchinf

○

TAMファイル管理

TAMファイルの初期作成

tamcre

×

TAMテーブルの状態表示

tamls

○

TAMテーブルの追加

tamadd

○

TAMテーブルの切り離し

tamrm

○

TAMテーブルの論理閉塞

tamhold

○

TAMテーブルの閉塞解除

tamrles

○

TAMテーブルのロード

tamload

○

TAMテーブルのアンロード

tamunload

○

TAMファイルの削除

tamdel

×

TAMファイルのバックアップ

tambkup

×

TAMファイルのリストア

tamrstr

×

TAMファイルの回復

tamfrc

×

TAM排他資源名称の変換

tamlckls

○

ハッシュ形式のTAMファイルおよびTAMテーブルのシノニム情報の表示

tamhsls

×

メッセージキューファイル管理

キューグループの状態表示

quels

○

メッセージキュー用物理ファイルの割り当て

queinit

×

メッセージキュー用物理ファイルの削除

querm

×

リソースマネジャ管理

リソースマネジャの情報の表示

trnlsrm

×

リソースマネジャの登録

trnlnkrm

×

トランザクション制御用オブジェクトファイルの作成

trnmkobj

×

トレース管理

UAPトレースの編集出力

uatdump

×

RPCトレースのマージ

rpcmrg

×

RPCトレースの出力

rpcdump

×

共用メモリダンプの出力

usmdump

○

性能検証用トレース管理

トレース情報ファイルの編集出力

prfed

×

トレース情報ファイルの取り出し

prfget

×

リアルタイム統計情報サービス管理

RTSログファイルの編集出力

rtsedit

×

リアルタイム統計情報の標準出力への出力

rtsls

×

リアルタイム統計情報サービスの実行環境の設定

rtssetup

×

リアルタイム統計情報の設定変更

rtsstats

×

OpenTP1解析支援

性能検証用トレース解析

dcalzprf

×

コネクション管理

コネクションの状態表示

mcftlscn

○

コネクションの確立

mcftactcn

○

コネクションの解放

mcftdctcn

○

コネクションの切り替え

mcftchcn

○

ネットワークの状態表示

mcftlsln

○

サーバ型コネクションの確立要求の受付開始

mcftonln

○

サーバ型コネクションの確立要求の受付終了

mcftofln

○

メッセージ多重処理状況の表示

mcftlstrd

○

アプリケーション管理

アプリケーションの状態表示

mcfalsap

○

アプリケーションの閉塞

mcfadctap

○

アプリケーションの閉塞解除

mcfaactap

○

アプリケーション異常終了回数の初期化

mcfaclcap

○

アプリケーション起動要求の状態表示

mcfalstap

○

アプリケーションに関するタイマ起動要求の削除

mcfadltap

○

アプリケーション運用支援

アプリケーションプログラムの起動

mcfuevt

○

論理端末管理

論理端末の状態表示

mcftlsle

○

論理端末の閉塞

mcftdctle

○

論理端末の閉塞解除

mcftactle

○

論理端末のメッセージキューの先頭スキップ

mcftspqle

○

論理端末の出力キュー処理の保留

mcfthldoq

○

論理端末の出力キュー処理の保留解除

mcftrlsoq

○

論理端末の出力キュー削除

mcftdlqle

○

論理端末に関するメッセージジャーナルの取得開始

mcftactmj

○

論理端末に関するメッセージジャーナルの取得終了

mcftdctmj

○

論理端末に対する継続問い合わせ応答処理の強制終了

mcftendct

○

端末代行の開始

mcftstalt

○

端末代行の終了

mcftedalt

○

サービスグループ管理

サービスグループの状態表示

mcftlssg

○

サービスグループの閉塞

mcftdctsg

○

サービスグループの閉塞解除

mcftactsg

○

サービスグループの入力キュー処理の保留

mcfthldiq

○

サービスグループの入力キュー処理の保留解除

mcftrlsiq

○

サービスグループの入力キュー削除

mcftdlqsg

○

サービス管理

サービスの状態表示

mcftlssv

○

サービスの閉塞

mcftdctsv

○

サービスの閉塞解除

mcftactsv

○

バッファ管理

バッファグループの使用状況表示

mcftlsbuf

○

マップ管理

マップファイルのパス名変更

dcmapchg

×

マップファイルのロード済み資源の表示

dcmapls

×

キュー管理

入出力キューの内容複写

mcftdmpqu

○

MCFトレース取得管理

MCFトレースファイルの強制スワップ

mcftswptr

○

MCFトレース取得の開始

mcftstrtr

○

MCFトレース取得の終了

mcftstptr

○

MCF稼働統計情報管理

MCF稼働統計情報の編集

mcfreport

×

MCF稼働統計情報の出力

mcfstats

○

MCF通信サービス管理

MCF通信サービスの部分停止

mcftstop

×

MCF通信サービスの部分開始

mcftstart

×

MCF通信サービスの状態参照と開始待ち合わせ

mcftlscom

×

ユーザタイマ監視

ユーザタイマ監視の状態表示

mcftlsutm

○

（凡例）

○：UAPの処理から実行できます。

×：UAPの処理から実行できません。

注※1

dcstopコマンドをUAPから実行する場合は，バックグラウンドで実行してください。

注※2

コマンドで変更された環境は，呼び出し元のUAPでは有効になりません。

2.4.2　ユーザサーバの開始処理完了の報告

ユーザサーバの開始処理が完了したことを報告するdc_adm_complete関数【CBLDCADM('COMPLETE')】は，SUPで必ず呼び出します。dc_rpc_open関数を呼び出したあとで，開始処理の完了をOpenTP1に連絡するために，dc_adm_complete関数を必ず呼び出してください。

SPPとMHPでは，dc_rpc_mainloop関数，またはdc_mcf_mainloop関数が正常に実行されたことで開始処理の完了と見なすので，dc_adm_complete関数を呼び出す必要はありません。

オフラインの業務をするUAPからは，dc_adm_complete関数を呼び出せません。

2.4.3　ユーザサーバの状態の検知

ユーザサーバが起動中かどうかなど，ユーザサーバの状態をUAPで知ることができます。UAPからdc_adm_status関数【CBLDCADM('STATUS ')】を呼び出すと，OpenTP1からユーザサーバの状態が返されます。

ユーザサーバの状態遷移を以降の図に示します。図に示すサーバの状態がOpenTP1から報告されます。

図2‒47　ユーザサーバの状態遷移（SUP）

図2‒48　ユーザサーバの状態遷移（SPP，MHP）

図2‒49　ユーザサーバの状態遷移（ソケット受信型サーバ　SPP）

2.5　メッセージログの出力

2.5.1　メッセージログをアプリケーションプログラムから出力

UAPからdc_logprint関数【CBLDCLOG('PRINT ')】を呼び出すと，ユーザ任意の情報をOpenTP1からのメッセージログとして出力できます。メッセージログはメッセージログファイルに出力されます。メッセージログファイルに出力された内容を表示するときは，logcatコマンドを実行して，標準出力に出力します。

メッセージログファイルへの出力と同時に，標準出力にリアルタイムに出力させることもできます。標準出力にリアルタイムで出力するかどうかは，ログサービス定義で指定します。

UAPからのメッセージログ出力の概要を次の図に示します。

図2‒50　UAPからのメッセージログ出力の概要

(1)　メッセージログとして出力する内容

メッセージログファイルに出力するメッセージログの情報の内容を次の表に示します。UAPから指定する項目は，要求元プログラムID，メッセージID，メッセージログテキストです。メッセージログファイルには次の表で示す情報とOpenTP1の制御コードが出力されます。

表2‒2　メッセージログファイルに出力するメッセージログの内容

番号

項目

出力される長さ

内容

−

行ヘッダ

メッセージログ通番

半角文字7けた

メッセージログ全体の通番です。障害が起こってメッセージログが抜けた場合は，このメッセージログ通番に抜けがあることでわかります。

プロセスID

半角数字10けた

または，半角数字5けた

（ログサービス定義の環境変数DCLOGDEFPIDに1を指定した場合は，半角数字5けた）

メッセージログ出力を指定したプロセスのIDを示します。

プロセス単位のメッセージログ通番

半角数字7けた

出力を要求したプロセス単位の，メッセージログの通番です。

1.

OpenTP1識別子

半角英数字2けた

OpenTP1システムごとの識別子です。

2.

日時

整数19けた

メッセージログの出力を要求した時間です。

「年／月／日　時：分：秒」の形式で出力されます。

3.

要求元ノード名

半角英数字8けた

メッセージログの出力を要求したUAPがあるノードの名称です。

ノード名の先頭8文字が出力されます。

4.

要求元プログラムID

半角英数字3けた

最初の1文字は「＊」で固定として，あとの2文字はUAPで指定した要求元プログラムIDが設定されます。

5.

メッセージID

半角英数字11けた

メッセージログ出力を要求したときに，UAPでメッセージログごとに付ける識別子です。メッセージIDの形式は次のとおりです。

KFCAn₁n₂n₃n₄n₅-x

KFCA：

固定部分です。

n₁n₂n₃n₄n₅：

UAPで指定する通番です。UAPで出力するメッセージログには，05000から06999までの通番が割り当てられています。

x：

メッセージログの種別を英字大文字で付けます。

E…エラーメッセージログ

I…通知メッセージログ

W…警告メッセージログ

R…応答要求メッセージログ

6.

メッセージログテキスト

可変長

最大222バイト

（Linux版だけ最大444バイト）

UAPが指定した任意の文字列です。

(2)　メッセージログの出力形式

UAPからdc_logprint関数で出力要求したメッセージログを，logcatコマンドで標準出力に表示する形式を次の図に示します。次の図はオプションを省略して入力した例です。logcatコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。図中の番号は表2-2と対応しています。

図2‒51　メッセージログの出力形式

(3)　NETMにメッセージを渡すときの注意

UAPから出力するメッセージログも，OpenTP1のメッセージログと同様に，統合ネットワーク管理システム（NETM）の操作支援端末に出力できます。NETMに出力するメッセージログの内容は次のとおりです。

行ヘッダの中の項目（ログサービス定義に指定）

メッセージID

メッセージテキスト

さらに，操作支援端末に出力するメッセージログの表示色を，UAPで設定できます。

UAPから出力するメッセージログをNETMに出力するときは，次のことに気を付けてください。

NETMに出力するメッセージログは，160バイト以下になるようにしてください。160バイトを超えると，NETMでメッセージを分割してVOS3に引き渡すので，一つのメッセージの行間に別のメッセージが混ざって出力される場合があります。また，メッセージログの長さが256バイトを超えると，OpenTP1のログサービスで256バイトを超える部分が切り捨てられます。

NETMに出力するメッセージテキストの中には，復改文字「¥n」を入れないようにしてください。「¥n」がある場合，NETMでメッセージを「¥n」で分割してVOS3に引き渡すので，一つのメッセージの行間に別のメッセージが混ざって出力される場合があります。

NETM：Integrated Network Management System

2.6　監査ログの出力

監査ログとは，システム構築者，運用者，および使用者がOpenTP1のプログラムに対して実行した操作，およびその操作に伴うプログラムの動作の履歴が出力されるファイルです。

OpenTP1では，UAPに対する操作の実行，UAP内の処理のタイミングなどで監査ログが出力されます。UAPから任意の監査ログを出力するには，dc_log_audit_print関数【CBLDCADT('PRINT ')】を呼び出します。

UAPから監査ログが出力される流れを次の図に示します。

図2‒52　UAPから監査ログが出力される流れ

監査ログファイルに出力される監査ログの項目とその内容を次の表に示します。出力される内容をUAPから指定できる項目は，メッセージID，発生コンポーネント名，監査事象の種別，監査事象の結果，動作情報，および自由記述です。

表2‒3　監査ログファイルに出力される監査ログの項目

出力の指定

項目

出力される長さ（最大バイト数）

内容

UAPから指定できる項目

メッセージID

11

監査ログの識別子

発生コンポーネント名

3

監査事象が発生したコンポーネントの名称

「*AA」の形式で出力されます。AAはdc_log_audit_print関数で指定した値です。

監査事象の種別

32

該当する監査事象のカテゴリ名

監査事象の結果

10

監査事象の結果

動作情報

32

該当事象を発生させたサブジェクトが指示したオブジェクトに対する行為（参照，追加，更新，削除など）

自由記述

1024

監査事象の内容を示す文字列

OpenTP1によって自動的に指定される項目

ヘッダ情報

12

監査ログのヘッダ情報

通番

7

監査ログの通番

日付・時刻

29

監査ログの取得日時

発生プログラム名

32

監査事象が発生したプログラムの名称

発生プロセスID

10

監査事象が発生したプロセスのプロセスID

発生場所

255

監査事象が発生したホストの識別情報

サブジェクト識別情報

256

監査事象を発生させた利用者の識別情報

オブジェクト情報

256

サービス名

サービス関数内で監査ログが出力される場合だけ，サービス名が出力されます。それ以外の場合は出力されません。

オブジェクトロケーション情報

64

ユーザサーバ名

リクエスト送信元ホスト

255

監査事象が複数のプログラム間での連係動作に関連する場合の，リクエスト送信元ホストのホスト識別情報

リクエスト送信元ホストの情報がない場合は出力されません。

ロケーション識別情報

64

環境変数DCDIRに設定されたパス名称

2.7　ユーザジャーナルの取得

UAPから任意の情報を，ユーザジャーナル（UJ）としてシステムジャーナルファイルに出力できます。ユーザジャーナルを取得するときは，UAPからdc_jnl_ujput関数【CBLDCJNL('UJPUT ')】を呼び出します。

ユーザジャーナルを取得する機能は，TP1/Server Baseの場合だけ使用できます。TP1/LiNKでは，UAPからユーザジャーナルを取得できません。

dc_jnl_ujput関数を呼び出して取得するユーザジャーナルの単位をUJレコードといいます。dc_jnl_ujput関数を1回呼び出すと，UJレコードを一つ取得できます。

UJレコードは，トランザクションの範囲外，またはトランザクションの範囲内で取得できます。トランザクションの範囲外で取得するUJレコードをトランザクション外UJと呼び，トランザクションの範囲内で取得するUJレコードをトランザクション内UJと呼びます。トランザクション外UJレコードは，ジャーナルバッファに空きがなくなったとき，またはほかのアプリケーションのトランザクションが正常終了した同期点（コミットした時点）で，システムジャーナルファイルに出力されます。

トランザクションが発生しないアプリケーションでUJレコードを取得する場合は，flagsにDCJNL_FLUSHを設定したdc_jnl_ujput関数を，適切なタイミングで呼び出してください。

ユーザジャーナルの取得を次の図に示します。

図2‒53　ユーザジャーナルの取得

dc_jnl_ujput関数を呼び出したトランザクションの処理に障害が起こった場合，ユーザジャーナルを取得した処理はロールバックで無効にはできません。dc_jnl_ujput関数を呼び出したUAPの処理を部分回復しても，UJレコードはシステムジャーナルファイルに出力されます。

2.8　ジャーナルデータの編集

jnlrputコマンドの実行結果をリダイレクトして出力したファイル（jnlrputコマンド出力ファイル）を，UAPから関数で編集できます。ジャーナルデータの編集は，COBOL言語のAPIでだけできます。C言語のAPIはありません。

UAPでは，次に示す手順で関数を呼び出します。

jnlrput出力ファイルを，CBLDCJUP('OPENRPT ')でオープンします。

ジャーナルデータを，CBLDCJUP('RDGETRPT')で入力します。ジャーナルデータの種別ごとに一つずつ入力します。必要なジャーナルデータをすべて入力するまで，CBLDCJUP('RDGETRPT')を呼び出します。

UAPの処理で編集します。

jnlrput出力ファイルを，CBLDCJUP('CLOSERPT')でクローズします。

ジャーナルデータを編集できるのは，オフラインの業務をするUAPだけです。ほかのUAPからは，jnlrputコマンド出力結果ファイルへアクセスしないでください。

ジャーナルデータを編集する機能は，TP1/Server Baseの場合だけ使えます。TP1/LiNKでは，ジャーナルデータを編集するAPIは使えません。

ジャーナルデータの編集を次の図に示します。

図2‒54　ジャーナルデータの編集

2.9　メッセージログ通知の受信

OpenTP1のメッセージログを，システム内に専用に作成するアプリケーションプログラムへ通知できます。通知を受信したアプリケーションプログラムは，他社のネットワーク管理システムへOpenTP1の状態を知らせることができます。

メッセージログを通知する場合は，OpenTP1のログサービス定義のlog_notify_outオペランドにYを指定しておいてください。

2.9.1　メッセージログの通知を受信できるアプリケーションプログラム

メッセージログの通知を受信できるのは，受信用に作成したアプリケーションプログラムだけです。OpenTP1のUAP（SUP，SPP，MHP）では，メッセージログ通知を受信できません。

通知を受信するときは，OpenTP1の関数を使います。アプリケーションプログラムの作成時には，OpenTP1のログサービスのヘッダファイルを取り込んで，OpenTP1のライブラリをリンケージしてください。

通知を受信するアプリケーションプログラムには，OpenTP1ホームディレクトリを示す環境変数DCDIRを設定しておいてください。この値は，メッセージログを通知するOpenTP1と同じ値にしてください。

OpenTP1のオンライン業務が開始以降のすべてのメッセージログを取得する場合，通知を受信するアプリケーションプログラムはOpenTP1よりも先に開始しておいてください。

2.9.2　メッセージログの通知の受信手順

通知を受信するアプリケーションプログラムは，受信の開始をdc_log_notify_open関数で宣言します。そして，dc_log_notify_receive関数でメッセージログを受信します。dc_log_notify_receive関数で受信できるメッセージログは一つです。複数のメッセージログを受信するには，dc_log_notify_receive関数を繰り返し呼び出します。

メッセージログの通知の受信を終了するときは，dc_log_notify_close関数を呼び出します。dc_log_notify_close関数を呼び出したあとでdc_log_notify_open関数を呼び出せば，再びメッセージログの通知を受信できます。

通知を受信するアプリケーションプログラムは，OpenTP1が終了したあとでもdc_log_notify_close関数を呼び出すまで待ち続けます。待ち続けているアプリケーションプログラムに受信処理の終了を知らせる場合には，ほかのアプリケーションプログラムからdc_log_notify_send関数でデータを送信します。受信処理の終了を知らせるアプリケーションプログラムでは，dc_log_notify_send関数を呼び出す前にdc_log_notify_open関数を呼び出せません。

メッセージログの通知の受信を次の図に示します。

図2‒55　メッセージログ通知の受信

2.9.3　メッセージログの通知を受信するときの注意

メッセージログの通知を受信するときの注意を，次に示します。

dc_log_notify_open関数，dc_log_notify_receive関数，dc_log_notify_close関数およびdc_log_notify_send関数は，割り込みルーチンからは実行できません。

dc_log_notify_receive関数を呼び出すタイミングによっては，OpenTP1からのメッセージログの通知を受信できない場合があります。受信できない場合を次に示します。

アプリケーションプログラムが停止している間，またはアプリケーションプログラムがdc_log_notify_open関数を呼び出す前かdc_log_notify_close関数を呼び出したあとにOpenTP1が出力したメッセージログ。

OpenTP1がメッセージログを通知していても，dc_log_notify_receive関数を呼び出していない場合に，通知されるメッセージログを退避しておくバッファに空きがなくなった以降のメッセージログ。

2.10　OSI TPを使ったクライアント／サーバ形態の通信

OpenTP1のクライアント／サーバ形態の通信では，TCP/IPとOSI TPを通信プロトコルに使えます。ここでは，通信プロトコルにOSI TPを使う場合の概要について説明します。通信プロトコルにOSI TPを使う場合には，TP1/NET/Library，TP1/NET/OSI-TP-ExtendedおよびOSI TPの通信管理をする製品が必要です。さらに，OpenTP1のシステムサービス（XATMI通信サービス）が必要です。

通信プロトコルにOSI TPを使ったクライアント／サーバ型の通信は，OpenTP1の基本機能がTP1/Server Baseの場合にだけできます。TP1/LiNKではOSI TP通信はできません。

OSI TPを使ったクライアント／サーバ形態の通信の形態を次の図に示します。

図2‒56　OSI TPを使ったクライアント／サーバ形態の通信の形態

2.10.1　OSI TP通信で使うアプリケーションプログラム

OpenTP1のUAPは，相手システムとの通信にXATMIインタフェースを使います。OSI TPを使ったクライアント／サーバ形態の通信で使えるOpenTP1のUAPは，SUPとSPPです。ほかのOpenTP1のUAP（MHP）は使えません。

UAPでは，ノード間の通信プロトコルを意識する必要はありません。

OpenTP1システムとOpenTP1システムでは，トランザクション処理を相手システム間で拡張できます。OpenTP1とOpenTP1以外のシステムでは，OSI TPを使ってトランザクション処理を相手システム間で拡張できます。

2.10.2　通信イベント処理用SPP

OSI　TPを使ったクライアント／サーバ形態の通信をする場合，アソシエーションの確立と解放を知るためのSPPを作成する必要があります。このSPPを通信イベント処理用SPPといいます。通信イベント処理用SPPを作成すると，アソシエーションの障害解放を通知する通信イベントを受信できます。この通信イベントを受信することで，アソシエーションの再確立のきっかけを知ることができます。また，通信イベント処理用SPPでは，通知された通信イベントの詳細情報から，アソシエーションの属性や状態について知ることができます。

アソシエーションが確立または解放されると，XATMI通信サービスは非応答型RPCでサービス要求する様式で，通信イベント処理用SPPを起動します。通信イベントは，自システムが発呼側か着呼側かどうかに関係なく通知されます。

通信イベント処理用SPPが受信する情報の内容については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

通信イベント処理用SPPの概要を次の図に示します。

図2‒57　通信イベント処理用SPPの概要

(1)　通信イベント処理用SPPに関連するシステム定義

通信イベント処理用SPPが通信イベントを受信できるようにするには，通信イベント処理用SPPのサービスグループ名とサービス名を，あらかじめXATMI通信サービス定義に指定しておきます。このとき，どのオペランドにサービスグループ名とサービス名を指定するかで，受け取れる通信イベントが異なります。

xat_aso_con_event_svcnameオペランド

アソシエーションの確立通知の通信イベント

xat_aso_discon_event_svcnameオペランド

アソシエーションの正常解放の通信イベント

xat_aso_failure_event_svcnameオペランド

アソシエーションの異常解放の通信イベント

複数のオペランドに同じサービスグループ名とサービス名を指定すると，一つの通信イベント処理用SPPが複数の通信イベントを受信できるようになります。

通信イベント処理用SPPのユーザサービス定義のserver_typeオペランドには，"betran"を指定してください。

(2)　通信イベント処理用SPPのアソシエーションの確立

通信イベント処理用SPPから関数を呼び出して，アソシエーションを確立できます。アソシエーションを確立するときは，dc_xat_connect関数【CBLDCXAT('CONNECT ')】を呼び出します。dc_xat_connect関数がリターンすると，正常に確立したことを受信する通信イベント処理用SPPでアソシエーションに関する情報を受け取れます。

dc_xat_connect関数で確立できるアソシエーションは，自システムが発呼側の場合だけです。また，関数のリターンとアソシエーションの確立は同期しないため，dc_xat_connect関数を呼び出したサービス関数では，確立を通知する通信イベントは受信できません。

(3)　アソシエーションの状態が通知されるタイミング

通知されるアソシエーションの確立には，次に示す場合があります。

OpenTP1システム開始時のアソシエーション確立

nettactcnコマンドの実行によるアソシエーション確立

通信イベント処理用SPPからの要求によるアソシエーション確立

相手システムからのアソシエーション確立

通知されるアソシエーションの解放には，次に示す場合があります。

nettactcnコマンドの実行によるアソシエーション強制解放

下位層の障害によるアソシエーションの解放

TP1/NET/OSI-TP-Extendedの障害によるアソシエーションの解放

XATMI通信サービスの障害によるアソシエーションの解放

アソシエーションの確立の失敗

相手システムからのアソシエーションの正常解放

相手システムからのアソシエーションの強制解放

2.10.3　OSI TP通信で障害が起こった場合

OSI TPを使ったクライアント／サーバ形態の通信で障害が起こった場合，サービスを要求したXATMIインタフェースの関数はエラーリターンします。どのリターン値が返るかについては，「OpenTP1 プログラム作成リファレンス」の該当する言語編にあるXATMIインタフェースの各関数の注意事項を参照してください。

通信プロトコルで障害が起こった場合の処置については，マニュアル「OpenTP1 プロトコル TP1/NET/OSI-TP-Extended編」の障害対策の記述を参照してください。

2.11　性能検証用トレースの取得

OpenTP1で動作する各種サービスの主なイベントでトレース情報を取得しています。これを性能検証用トレース（prfトレース）といいます。性能検証用トレースは，性能検証の効率，およびトラブルシュートの効率を向上させることが目的のトレース情報です。性能検証用トレースには，次のような特徴があります。

ノードおよびプロセスにわたる場合でもトレースを追うことができます。

APIの単位でなく，内部のイベント単位でトレースを取得できるので，どの処理が性能ネックか検証できます。

なお，この機能は，TP1/Extension 1をインストールしていることが前提です。TP1/Extension 1をインストールしていない場合の動作は保証できませんので，ご了承ください。

UAPからユーザ固有の性能検証用トレースを取得するには，dc_prf_utrace_put関数【CBLDCPRF('PRFPUT ')】を呼び出します。

また，最新の性能検証用トレースのプロセス内での取得通番を知るには，dc_prf_get_trace_num関数【CBLDCPRF('PRFGETN ')】を呼び出します。dc_prf_get_trace_num関数呼び出し元に，最新の性能検証用トレースのプロセス内での取得通番を通知します。

2.12　リアルタイム統計情報の取得

UAP内の任意区間での処理の実行時間および実行回数を，リアルタイム統計情報として取得できます。オフラインの業務をするUAPでは，任意区間でのリアルタイム統計情報は取得できません。

任意区間でのリアルタイム統計情報を取得する場合は，UAPからdc_rts_utrace_put関数【CBLDCRTS('RTSPUT ')】を呼び出します。

取得する項目はevent_idに，取得に関する動作はflagsに設定します。flagsでは，次の表に示す動作を設定できます。

表2‒4　dc_rts_utrace_put関数のflagsの設定

flagsの設定

取得に関する動作

DCRTS_START

実行時間の計測を開始

DCRTS_END

実行時間を取得して，計測を終了

DCNOFLAGS

実行回数だけを取得

dc_rts_utrace_put関数で取得した実行回数および実行時間は，event_idに設定した項目IDのリアルタイム統計情報として編集，出力します。

任意区間でのリアルタイム統計情報の取得の例を次の図に示します。

図2‒58　任意区間でのリアルタイム統計情報の取得の例

項目ID1の実行時間の計測を開始します。

項目ID2の実行時間の計測を開始します。

項目ID1の実行時間の計測を終了して，実行時間および実行回数の情報を，RTSサービス用の共用メモリに取得します。

項目ID2の実行時間の計測を終了して，実行時間および実行回数の情報を，RTSサービス用の共用メモリに取得します。

3　TP1/Message Controlを使う場合の機能

メッセージ送受信機能（TP1/Message Control）を使うアプリケーションプログラムで使える機能について説明します。

この章では，各機能をC言語の関数名で説明します。C言語の関数名に該当するCOBOL言語のAPIは，関数を最初に説明する個所に【 】で囲んで表記します。それ以降は，C言語の関数名に統一して説明します。

3.1　MCF通信サービスに関する運用

ここでは，MCF通信サービスに関する運用について説明します。運用コマンドによるMCF通信サービスに関する運用については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.1.1　MCF通信サービスの状態表示

MCF通信サービスおよびアプリケーション起動プロセスの状態は，dc_mcf_tlscom関数【CBLDCMCF('TLSCOM ')】で表示できます。表示内容はMCF通信サーバ名，MCF通信サーバのプロセスID，MCF通信サービスの状態などです。

3.1.2　APIと運用コマンドの機能差異（MCF通信サービスに関する運用）

MCF通信サービスに関する運用で使用する関数と運用コマンドの機能差異について，次の表に示します。

表3‒1　関数と運用コマンドの機能差異（MCF通信サービスに関する運用）

関数名

運用コマンド名

機能差異

dc_mcf_tlscom

mcftlscom

すべてのMCF通信サービスの状態を取得します。特定のMCF通信サービスの状態は取得できません。

MCF通信サービスのプロセスIDは取得できません。

MCF通信サービスの開始待ち合わせはできません。

3.2　コネクションの確立と解放

TP1/Messaging Controlを使用して，メインフレームやWSとメッセージ送受信形態で通信する場合，自システムと相手システムとの間に論理的な通信路（コネクション）を確立します。

ここでは，UAPからの関数の発行によるコネクションの確立と解放について説明します。運用コマンドによるコネクションの確立と解放については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.2.1　UAPからの関数の発行によるコネクションの確立と解放

コネクションの確立には，dc_mcf_tactcn関数【CBLDCMCF('TACTCN ')】を使用し，コネクションの解放には，dc_mcf_tdctcn関数【CBLDCMCF('TDCTCN ')】を使用します。さらに，dc_mcf_tlscn関数【CBLDCMCF('TLSCN ')】でコネクションの状態を取得できます。

なお，TP1/NET/UDPでは，コネクション管理の関数は使用できません。

(1)　コネクションの確立

dc_mcf_tactcn関数を発行すると，MCF通信プロセスに相手システムとのコネクション確立を要求します。

使用するプロトコルによっては，相手システムとコネクションが確立されたときやコネクションの確立に失敗したときに，MCFイベントでUAPに通知されます。TP1/NET/TCP/IP上でdc_mcf_tactcn関数を使用した場合を例に，コネクションを確立する流れを次の図に示します。

図3‒1　dc_mcf_tactcn関数を使用したコネクション確立の例

(2)　コネクションの解放

dc_mcf_tdctcn関数を発行すると，MCF通信プロセスに相手システムとのコネクション解放を要求します。

使用するプロトコルによっては，コネクションの解放はMCFイベントでUAPに通知されます。TP1/NET/TCP/IP上でdc_mcf_tdctcn関数を使用した場合を例に，コネクションを解放する流れを次の図に示します。

図3‒2　dc_mcf_tdctcn関数を使用したコネクション解放の例

(3)　APIと運用コマンドの機能差異（コネクションの確立と解放）

コネクションの確立と解放で使用する関数と運用コマンドの機能差異について，次の表に示します。

表3‒2　関数と運用コマンドの機能差異（コネクションの確立と解放）

関数名

運用コマンド

機能差異

dc_mcf_tactcn

mcftactcn

一つのコネクションに確立を要求します。コネクションの複数指定，および一括指定はできません。

コネクショングループへの確立は要求できません。

サブコネクションは指定できません。

接続するXPサービスは指定できません。

dc_mcf_tdctcn

mcftdctcn

一つのコネクションに解放を要求します。コネクションの複数指定，および一括指定はできません。

コネクショングループへの解放は要求できません。

サブコネクションは指定できません。

dc_mcf_tlscn

mcftlscn

一つのコネクションの状態を取得します。コネクションの複数指定，および一括指定はできません。

コネクショングループの状態は取得できません。

プロトコル種別，コネクション状態だけを取得できます。その他の付加情報やプロトコル固有情報は取得できません。

3.2.2　コネクションを再確立・強制解放する場合のコーディング例

ここでは，コネクションを再確立・強制解放する場合の，コーディング例を示します。

(1)　コネクションを再確立する場合のコーディング例

CERREVT（コネクション障害）が通知されたあと，コネクションを自動的に再確立する場合の例を，次の図およびコーディング例に示します。

図3‒3　コネクションを自動的に再確立するUAPの例

void cerrevt(){
    char    rcvdata[256];
    DCLONG  rcv_len;
    DCLONG  rtime;
    int     rtn;
    dcmcf_tactcnopt cnopt;
    dcmcf_tlscnopt  cnopt2;
    DCLONG  infcnt = 1;
    dcmcf_cninf     inf;

    rtn = dc_mcf_receive(DCMCFFRST, DCNOFLAGS, termnam, "", rcvdata,
                         &rcv_len, sizeof(rcvdata), &rtime);
    if (DCMCFRTN_00000 == rtn){

        /* コネクション解放時の処理 */
        /*            :             */

        /* コネクションの再確立要求 */
        memset(&cnopt, 0, sizeof(cnopt));
        strcpy(cnopt.idnam, termnam);

        rtn = dc_mcf_tactcn(DCMCFLE , &cnopt, NULL, NULL, NULL, NULL);
        if (DCMCFRTN_00000 == rtn){
            /* コネクション確立要求の受付：成功 */

            while(1){
                /* コネクションの状態取得 */
                memset(&cnopt2, 0, sizeof(cnopt2));
                strcpy(cnopt2.idnam, termnam);
                memset(&inf, 0, sizeof(inf));

                rtn = dc_mcf_tlscn(DCMCFLE, &cnopt2, NULL, NULL, NULL, &infcnt, &inf, NULL);
                if (DCMCFRTN_00000 == rtn){
                    if (DCMCF_CNST_ACT == inf.status){
                        /* コネクション確立状態 */
                        break;
                    }
                } else {
                    /* 障害処理 */
                }
                sleep(1);
            }

            /* コネクション確立後の処理 */
            /*         :                */

        } else {
            /* コネクション確立要求の受付：失敗 */
            /* 障害処理 */
        }

    } else {
        /* 障害処理 */
    }

    return;
}

(2)　コネクションを強制解放する場合のコーディング例

受信したメッセージに形式誤りがあったときにコネクションを強制解放する場合の例を，次の図およびコーディング例に示します。

図3‒4　コネクションを強制解放するUAPの例

void mhprecv(){
    char    rcvdata[256];
    DCLONG  rcv_len;
    DCLONG  rtime;
    int     rtn;
    int     check;
    dcmcf_tdctcnopt cnopt;
    dcmcf_tlscnopt  cnopt2;
    DCLONG  infcnt = 1;
    dcmcf_cninf     inf;

    rtn = dc_mcf_receive(DCMCFFRST, DCNOFLAGS, termnam, "", rcvdata,
                         &rcv_len, sizeof(rcvdata), &rtime);
    if (DCMCFRTN_00000 == rtn){

        /* 受信メッセージのチェック処理 */
        /*            ：                */

        if (0 == check){
            /* チェック結果：正 */
            /* 正常時の処理 */
        } else {
            /* チェック結果：誤 */

            /* コネクションの強制解放要求 */
            memset(&cnopt, 0, sizeof(cnopt));
            strcpy(cnopt.idnam, termnam);

            rtn = dc_mcf_tdctcn(DCMCFLE | DCMCFFRC, &cnopt, NULL, NULL, NULL, NULL);
            if (DCMCFRTN_00000 == rtn){
                /* コネクション強制解放要求の受付：成功 */

                while(1){
                    /* コネクションの状態取得 */
                    memset(&cnopt2, 0, sizeof(cnopt2));
                    strcpy(cnopt2.idnam, termnam);
                    memset(&inf, 0, sizeof(inf));

                    rtn = dc_mcf_tlscn(DCMCFLE, &cnopt2, NULL, NULL, NULL, &infcnt, &inf, NULL);
                    if (DCMCFRTN_00000 == rtn){
                        if (DCMCF_CNST_DCT == inf.status){
                            /* コネクション解放状態 */
                            break;
                        }
                    } else {
                        /* 障害処理 */
                    }
                    sleep(1);
                }

                /* コネクション解放後の処理 */
                /*         ：               */

            } else {
                /* コネクション強制解放要求の受付：失敗 */
                /* 障害処理 */
            }
        }

    } else {
        /* 障害処理 */
    }

    return;
}

3.2.3　コネクションの確立要求の受付開始と終了

コネクションの確立要求の受付を開始するには，dc_mcf_tonln関数【CBLDCMCF('TONLN ')】を使用します。一方，コネクションの確立要求の受付を終了するには，dc_mcf_tofln関数【CBLDCMCF('TOFLN ')】を使用します。また，dc_mcf_tlsln関数【CBLDCMCF('TLSLN ')】で確立要求の受付状態を取得できます。

詳細については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

(1)　APIと運用コマンドの機能差異（コネクションの確立要求の受付開始と終了）

コネクションの確立要求の受付開始と終了で使用する関数と運用コマンドの機能差異について，次の表に示します。

表3‒3　関数と運用コマンドの機能差異（コネクションの確立要求の受付開始と終了）

関数名

運用コマンド

機能差異

dc_mcf_tlsln

mcftlsln

対象となるMCF通信プロセスのMCF通信プロセス識別子を指定する必要があります。また，すべてのMCF通信プロセスの，サーバ型コネクションの確立要求の受付状態は取得できません。

サーバ型コネクションの確立要求の受付状態だけを取得できます。その他の付加情報は取得できません。

dc_mcf_tofln

mcftofln

ありません。

dc_mcf_tonln

mcftonln

ありません。

3.3　アプリケーションに関する運用

ここでは，アプリケーションに関する運用について説明します。運用コマンドによるアプリケーションに関する運用については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.3.1　アプリケーションに関するタイマ起動要求の削除

タイマ起動要求をしたアプリケーションの起動を停止するには，dc_mcf_adltap関数【CBLDCMCF('ADLTAP ')】を使用します。dc_mcf_adltap関数を発行すると，指定されたアプリケーションに対するタイマ起動要求を削除し，アプリケーションの起動を停止できます。

3.3.2　APIと運用コマンドの機能差異（アプリケーションに関する運用）

アプリケーションに関する運用で使用する関数と運用コマンドの機能差異について，次の表に示します。

表3‒4　関数と運用コマンドの機能差異（アプリケーションに関する運用）

関数名

運用コマンド

機能差異

dc_mcf_adltap

mcfadltap

一つのアプリケーションのタイマ起動要求を削除します。アプリケーションの複数指定，および一括指定はできません。

対象となるアプリケーション起動プロセスの，アプリケーション起動プロセス識別子を指定する必要があります。また，すべてのアプリケーション起動プロセスのタイマ起動要求は削除できません。

3.4　論理端末の閉塞と閉塞解除

ここでは，UAPからの関数の発行による論理端末の閉塞と閉塞解除について説明します。運用コマンドによる論理端末の閉塞と閉塞解除については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.4.1　論理端末の状態表示

論理端末の状態は，dc_mcf_tlsle関数【CBLDCMCF('TLSLE ')】で表示できます。表示できる内容は，MCF識別子，論理端末名称，論理端末状態（閉塞状態，または閉塞解除状態）などです。

論理端末の状態はUAP中で指定した領域に格納されます。

3.4.2　論理端末の閉塞と閉塞解除

論理端末の閉塞状態とは，UAPが送信要求したメッセージを，相手システムに送信できない状態です。この状態でUAPが送信要求した場合，送信要求は正常に受け付けられますが，送信メッセージは出力キューに滞留します。また，この状態のとき，相手システムからの受信メッセージのスケジュールは，正常に行われます。

論理端末を閉塞するには，dc_mcf_tdctle関数【CBLDCMCF('TDCTLE ')】を使用します。閉塞中の一方送信メッセージの送信要求は，出力キューに滞留します。なお，論理端末は障害によって閉塞することもあります。

一方，論理端末の閉塞解除状態とは，論理端末が持つ機能を使用できる状態です。

論理端末の閉塞を解除するには，dc_mcf_tactle関数【CBLDCMCF('TACTLE ')】を使用します。閉塞が解除されると，出力キューに残っているメッセージが送信されます。なお，コネクションが未確立の場合は，論理端末の閉塞解除はできません。

3.4.3　論理端末の出力キュー削除

コネクションの確立後，出力キューに残っているメッセージを破棄するには，dc_mcf_tdlqle関数【CBLDCMCF('TDLQLE ')】を使用します。

dc_mcf_tdlqle関数を発行すると，ディスクキューとメモリキューの出力キューに残っているすべてのメッセージを削除し，削除したメッセージごとにMCFイベントを起動します。ただし，dc_mcf_tdlqle関数を発行するためには，あらかじめmcftdctleコマンドまたはdc_mcf_tdctle関数で論理端末を閉塞しておく必要があります。

3.4.4　APIと運用コマンドの機能差異（論理端末の閉塞と閉塞解除）

論理端末の閉塞と閉塞解除で使用する関数と運用コマンドの機能差異について，次の表に示します。

表3‒5　関数と運用コマンドの機能差異（論理端末の閉塞と閉塞解除）

関数名

運用コマンド

機能差異

dc_mcf_tactle

mcftactle

一つの論理端末に閉塞解除を要求します。論理端末の複数指定，および一括指定はできません。

論理端末の端末状態，およびキュー状態の，両方の閉塞を解除します。どちらか片方だけを指定することはできません。

dc_mcf_tdctle

mcftdctle

一つの論理端末に閉塞を要求します。論理端末の複数指定，および一括指定はできません。

論理端末の端末状態およびキュー状態の両方を閉塞します。どちらか片方だけを指定することはできません。

dc_mcf_tdlqle

mcftdlqle

一つの論理端末に出力キューの削除を要求します。論理端末の複数指定，および一括指定はできません。

ディスクキューおよびメモリキューの，両方を削除します。どちらか片方だけを指定することはできません。

MCFアプリケーション定義に未処理送信メッセージ廃棄通知イベント（ERREVTA）が定義されている場合，ERREVTAを通知します。通知を抑止することはできません。

dc_mcf_tlsle

mcftlsle

一つの論理端末の状態を取得します。論理端末の複数指定，および一括指定はできません。

論理端末状態だけを取得できます。その他の付加情報は取得できません。

最大未送信メッセージ数をリセットできません。

3.5　通信プロトコル対応製品と運用操作で使える関数

ここでは，通信プロトコル対応製品と運用操作で使える関数の対応について説明します。運用操作とは，次の操作を指します。

MCF通信サービスに関する運用

コネクションの確立と解放

アプリケーションに関する運用

論理端末の閉塞と閉塞解除

通信プロトコル対応製品と運用操作で使える関数の対応を，以降の表に示します。

表3‒6　通信プロトコル対応製品と運用操作で使える関数1

関数名

通信プロトコル対応製品

TP1/NET/OSAS-NIF

TP1/NET/OSI-TP

TP1/NET/SLU - TypeP2

TP1/NET/TCP/IP

dc_mcf_adltap

○

○

○

○

dc_mcf_tactcn

○

○

○

○

dc_mcf_tactle

○

×

○

○

dc_mcf_tdctcn

○

○

○

○

dc_mcf_tdctle

○

×

○

○

dc_mcf_tdlqle

○

×

○

○

dc_mcf_tlscn

○

○

○

○

dc_mcf_tlscom

○

○

○

○

dc_mcf_tlsle

○

×

○

○

dc_mcf_tlsln

×

×

×

○

dc_mcf_tofln

×

×

×

○

dc_mcf_tonln

×

×

×

○

（凡例）

○：使えます。

×：使えません。

表3‒7　通信プロトコル対応製品と運用操作で使える関数2

関数名

通信プロトコル対応製品

TP1/NET/User Agent

TP1/NET/UDP

TP1/NET/XMAP3

dc_mcf_adltap

○

○

○

dc_mcf_tactcn

○

×

○

dc_mcf_tactle

○

○

○

dc_mcf_tdctcn

○

×

○

dc_mcf_tdctle

○

○

○

dc_mcf_tdlqle

○

○

○

dc_mcf_tlscn

○

×

○

dc_mcf_tlscom

○

○

○

dc_mcf_tlsle

○

○

○

dc_mcf_tlsln

×

×

×

dc_mcf_tofln

×

×

×

dc_mcf_tonln

×

×

×

（凡例）

○：使えます。

×：使えません。

3.6　メッセージ送受信

OpenTP1の基本機能（TP1/Server Base）にTP1/Message Controlを組み込んで使うと，広域ネットワーク（WAN）やTCP/IP，および従来型のネットワークを介して，メインフレームやWSとメッセージ送受信形態で通信できます。

メッセージを使って通信する場合は，MHPを使います。また，一部のメッセージ処理はSPPでも使えます。

メッセージ送受信機能は，システムにTP1/Message Controlが組み込まれていることが前提となります。また，OpenTP1の基本機能がTP1/Server Baseの場合だけ使えます。TP1/LiNKでMHPを作成するときは，TP1/Messagingが必要です。

メッセージ送受信形態の通信の概要を次の図に示します。

図3‒5　メッセージ送受信形態の通信の概要

UOCについて

UAPによるメッセージの処理を，より多様な業務に対応させるために，ユーザオウンコーディング（UOC）を作成できます。UOCは業務に合わせて任意に作成します。

UOCの概要については，「3.9　ユーザオウンコーディング（UOC）」を参照してください。

3.6.1　メッセージの通信形態

(1)　MHPで使えるメッセージの通信形態

MHPで使えるメッセージの通信形態を次に示します。使えるメッセージの通信形態は，通信プロトコル別で異なります。

問い合わせ応答形態

相手システムからdc_mcf_receive関数【CBLDCMCF('RECEIVE ')】でメッセージを受け取って，dc_mcf_reply関数【CBLDCMCF('REPLY ')】で応答メッセージを返す形態です。

非問い合わせ応答形態（一方受信形態）

相手システムからdc_mcf_receive関数でメッセージを受け取ったあとに，応答メッセージを返さない形態です。

継続問い合わせ応答形態

問い合わせ応答形態を連続させる形態です。dc_mcf_receive関数でメッセージを受け取って，dc_mcf_reply関数で応答メッセージを返してから，続けて問い合わせ応答の処理をします。継続問い合わせ応答はdc_mcf_contend関数【CBLDCMCF('CONTEND ')】で終了させます。

メッセージの通信形態を次の図に示します。

図3‒6　メッセージの通信形態

(2)　MHPの各通信形態，およびSPPで任意に使えるメッセージ通信機能

MHPとSPPで任意に使えるメッセージ通信機能を次に示します。

分岐送信

自システムからdc_mcf_send関数【CBLDCMCF('SEND ')】でメッセージを送信できます。

同期送信，同期受信，同期送受信

相手システムからのメッセージ受信後に，メッセージを同期的に送信（dc_mcf_sendsync関数【CBLDCMCF('SENDSYNC')】），同期的に受信（dc_mcf_recvsync関数【CBLDCMCF('RECVSYNC')】），および同期的に送受信（dc_mcf_sendrecv関数【CBLDCMCF('SENDRECV')】）できます。送信処理または受信処理が完了するまで，関数はリターンしません。

SPPからdc_mcf_send関数を呼び出す場合は，そのSPPの処理はトランザクションとして稼働していることが前提です。

(3)　メッセージの通信形態とアプリケーションの型

メッセージ送受信機能を使うMHPは，使うメッセージの通信形態によってアプリケーションの型を指定しておきます。アプリケーションの型は，MCFアプリケーション定義アプリケーション属性定義（mcfaalcap）のtypeオペランドで指定します。アプリケーションの型には次の三つがあります。

応答型（ans型）：問い合わせ応答形態のMHP。

非応答型（noans型）：非問い合わせ応答形態のMHP。

継続問い合わせ応答型（cont型）：継続問い合わせ応答形態のMHP。

dc_mcf_receive関数で受信したメッセージを，dc_mcf_send関数で入力元の論理端末に送信する形態も，noans型とします。

MHPには，メッセージを処理する形態に合ったアプリケーションの型を指定してください。

指定したアプリケーションの型とメッセージを処理する形態に矛盾がある場合は，メッセージ送受信の関数がエラーリターンするか，またはMHPの処理がロールバックされます。矛盾がある例を次に示します。

応答型のMHPで，dc_mcf_reply関数を使わないで終了した場合，またはほかの応答型のMHPをdc_mcf_execap関数【CBLDCMCF('EXECAP ')】で起動しないで終了した場合

非応答型のMHPでdc_mcf_reply関数を使った場合（非応答型のMHPからの問い合わせ応答をしない（UAP共通定義（mcfmuap）の-cオプションのnoansreplyオペランドにnoを指定）場合）

MCFイベント処理用MHPのアプリケーションの型は，通知されたMCFイベントによって決まります。MCFイベント処理用MHPのアプリケーションの型については，「3.10　MCFイベント」を参照してください。

アプリケーションの型と使えるメッセージ送受信関数を次の表に示します。

表3‒8　アプリケーションの型と使えるメッセージ送受信関数

メッセージの形態

アプリケーションの型

メッセージを処理する関数

receive

send

reply

sendrecv

recvsync

sendsync

tempput，

tempget，

contend

問い合わせ応答形態

ans型

◎

○

◎

△※1

△※1

−

−

非問い合わせ応答形態（一方受信形態）

noans型

◎

○

○※2

△

△

△

−

継続問い合わせ応答形態

cont型

◎

○

◎

−

−

−

○

（凡例）

◎：必ず使います。

○：使えます。

△：プロトコル製品によって異なります。詳細については「3.6.1(4)　通信プロトコル対応製品と通信形態で使える関数」を参照してください。

−：使えません。

注※1

TP1/NET/User AgentまたはTP1/NET/OSAS-NIFを使った場合に呼び出せます。ただし，dc_mcf_recvsync関数は，複数セグメントを送信したdc_mcf_sendrecv関数を呼び出したときに，先頭セグメント以外のセグメントを受け取る目的にだけ使えます。

注※2

非応答型のMHPからの問い合わせ応答をする（UAP共通定義（mcfmuap）の-cオプションのnoansreplyオペランドにyesを指定）場合に呼び出せます。

(4)　通信プロトコル対応製品と通信形態で使える関数

通信プロトコル対応製品と通信形態別で使える関数の対応を，以降の表に示します。

表3‒9　通信プロトコル対応製品と通信形態で使える関数1

関数名

通信プロトコル対応製品とアプリケーションの型

TP1/NET/OSAS-NIF

TP1/NET/OSI-TP

TP1/NET/SLU - TypeP2

noans型

ans型

cont型

noans型

ans型

cont型

noans型

ans型

cont型

dc_mcf_commit

○

×

−

○

−

−

○

−

−

dc_mcf_receive※

○

○

−

○

−

−

○

−

−

dc_mcf_execap

○

○

−

×

−

−

○

−

−

dc_mcf_reply※

△

○

−

×

−

−

×

−

−

dc_mcf_rollback

○

○

−

○

−

−

○

−

−

dc_mcf_send※

○

○

−

×

−

−

○

−

−

dc_mcf_resend※

○

○

−

×

−

−

○

−

−

dc_mcf_sendrecv※

○

○

−

○

−

−

○

−

−

dc_mcf_sendsync※

×

×

−

○

−

−

×

−

−

dc_mcf_recvsync※

□

□

−

○

−

−

□

−

−

dc_mcf_contend

×

×

−

×

−

−

×

−

−

dc_mcf_tempget

×

×

−

×

−

−

×

−

−

dc_mcf_tempput

×

×

−

×

−

−

×

−

−

（凡例）

○：該当する通信プロトコル対応製品で使えます。

×：使えません。

□：通信プロトコル対応製品で固有な使い方をします。

△：非応答型のMHPからの問い合わせ応答をする（UAP共通定義（mcfmuap）の-cオプションのnoansreplyオペランドにyesを指定）場合に使えます。

−：該当する通信プロトコル対応製品では使えない通信形態です。

注※

通信プロトコル対応製品によって，関数の使い方が異なる場合があります。詳細については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

表3‒10　通信プロトコル対応製品と通信形態で使える関数2

関数名

通信プロトコル対応製品とアプリケーションの型

TP1/NET/TCP/IP

TP1/NET/User Agent

noans型

ans型

cont型

noans型

ans型

cont型

dc_mcf_commit

○

×

×

○

×

−

dc_mcf_receive※

○

○

○

○

○

−

dc_mcf_execap

○

○

○

○

○

−

dc_mcf_reply※

△

○

○

△

○

−

dc_mcf_rollback

○

○

○

○

○

−

dc_mcf_send※

○

○

○

○

○

−

dc_mcf_resend※

○

○

○

○

○

−

dc_mcf_sendrecv※

○

×

×

○

○

−

dc_mcf_sendsync※

○

×

×

×

×

−

dc_mcf_recvsync※

○

×

×

□

□

−

dc_mcf_contend

×

×

○

×

×

−

dc_mcf_tempget

×

×

○

×

×

−

dc_mcf_tempput

×

×

○

×

×

−

（凡例）

○：該当する通信プロトコル対応製品で使えます。

×：使えません。

□：通信プロトコル対応製品で固有な使い方をします。

△：非応答型のMHPからの問い合わせ応答をする（UAP共通定義（mcfmuap）の-cオプションのnoansreplyオペランドにyesを指定）場合に使えます。

−：該当する通信プロトコル対応製品では使えない通信形態です。

注※

通信プロトコル対応製品によって，関数の使い方が異なる場合があります。詳細については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

表3‒11　通信プロトコル対応製品と通信形態で使える関数3

関数名

通信プロトコル対応製品とアプリケーションの型

TP1/NET/UDP

TP1/NET/XMAP3

noans型

ans型

cont型

noans型

ans型

cont型

dc_mcf_commit

○

−

−

○

×

×

dc_mcf_receive※

○

−

−

○

○

○

dc_mcf_execap

○

−

−

○

○

○

dc_mcf_reply※

×

−

−

△

○

○

dc_mcf_rollback

○

−

−

○

○

○

dc_mcf_send※

○

−

−

○

○

○

dc_mcf_resend※

○

−

−

○

○

○

dc_mcf_sendrecv※

×

−

−

×

×

×

dc_mcf_sendsync※

○

−

−

×

×

×

dc_mcf_recvsync※

×

−

−

×

×

×

dc_mcf_contend

×

−

−

×

×

○

dc_mcf_tempget

×

−

−

×

×

○

dc_mcf_tempput

×

−

−

×

×

○

（凡例）

○：該当する通信プロトコル対応製品で使えます。

×：使えません。

△：非応答型のMHPからの問い合わせ応答をする（UAP共通定義（mcfmuap）の-cオプションのnoansreplyオペランドにyesを指定）場合に使えます。

−：該当する通信プロトコル対応製品では使えない通信形態です。

注※

通信プロトコル対応製品によって，関数の使い方が異なる場合があります。詳細については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

3.6.2　メッセージの構造

メッセージの構造について説明します。

(1)　論理メッセージとセグメント

システム間で通信する上で意味を持つデータの単位を論理メッセージといいます。論理メッセージは，一つまたは複数のセグメントから構成されます。セグメントとは，UAPの処理からライブラリ関数の呼び出し1回で処理できる単位です。

論理メッセージが一つのセグメントから構成されるときは，関数呼び出し1回でメッセージを処理できます。論理メッセージが複数のセグメントから構成されるときは，セグメントの数だけ関数を呼び出して，メッセージを処理します。

(2)　セグメントの構造

セグメントは，MCFで使うヘッダ領域とセグメントのデータから構成されます。ヘッダ領域には，長さによってバッファ形式1とバッファ形式2の2種類があります。どちらの形式のヘッダ領域を使うかは，ユーザ任意です。ただし，TP1/NET/XMAP3を使う場合は，バッファ形式2だけを使えます。

ヘッダ領域の長さは，通信プロトコル対応製品によって異なります。ヘッダ領域の長さについては，マニュアル「OpenTP1 プロトコル」のメッセージ送受信APIの説明を参照してください。

論理メッセージとセグメントの関係を次の図に示します。

図3‒7　論理メッセージとセグメントの関係

3.6.3　メッセージの受信

他システムから送信されたメッセージを最終セグメントまで受信すると，MCFはアプリケーション名に該当するMHPにメッセージを渡します。MHPではメッセージをdc_mcf_receive関数【CBLDCMCF('RECEIVE ')】で受信して処理を開始します。このメッセージ受信を非同期型のメッセージ受信といいます。

dc_mcf_receive関数では，メッセージをセグメント単位で受信します。

メッセージが一つのセグメント（単一セグメント）から構成される場合は，dc_mcf_receive関数を1回だけ呼び出します。

メッセージが複数のセグメントから構成されるときは，dc_mcf_receive関数をセグメントの数だけ呼び出して受信します。MHPでは，メッセージを先頭セグメントから受信して，次に中間以降のセグメントを受信します。中間以降のセグメントを受信し続けると，受信するセグメントがないことを知らせるリターン値が返るので，最終セグメントまで受信し終わったことがわかります。

UOCを使うと，MHPにメッセージを渡す前にメッセージを編集したり，アプリケーション名を変更したりできます。

アプリケーション名

アプリケーション名は，メッセージの先頭から，空白の手前までの1から8バイトの英数字です。先頭から9バイト目までに空白がないとき，または先頭が空白のときは，間違ったアプリケーション名と見なします。

アプリケーション名は，入力メッセージ編集UOCで編集できます。

メッセージの受信を次の図に示します。

図3‒8　メッセージの受信

3.6.4　メッセージの送信

OpenTP1では，セグメントを送信するUAPのすべての処理が終了したあとで（MHPの終了，またはSPPのトランザクション正常終了），それまでUAPから送信したセグメントを一括してメッセージとして送信します。これを非同期型のメッセージ送信といいます。一方送信メッセージはdc_mcf_send関数【CBLDCMCF('SEND ')】，応答メッセージはdc_mcf_reply関数【CBLDCMCF('REPLY ')】を使います。

非同期型のメッセージ送信では，関数がセグメントを送信したあとにUAPのプロセスが異常終了，またはメッセージ処理ができなくてロールバックとなった場合，それまでにUAPから出力していたセグメントの送信はすべて無効となります。

UAPからセグメントを送信してから実際に出力される前に，UOCで出力通番の編集や出力メッセージの編集など，任意の処理ができます。

メッセージの送信を次の図に示します。

図3‒9　メッセージの送信（非同期型のメッセージ送信）

3.6.5　同期型のメッセージ処理

MHPの処理の途中でメッセージの送信完了を確認したいときや，UAPのメッセージ送受信の処理をシステム間で同期を取りたいときに，同期型のメッセージを使います。同期型のメッセージ送受信では，送信または受信を要求して，その処理がすべて完了してから，UAPから呼び出した関数がリターンします。

(1)　同期型のメッセージの種類

同期型のメッセージ送受信には，送信，および受信をそれぞれ単独でする関数と，送受信を連続してする関数があります。

同期型のメッセージ送信

同期型のメッセージ送信をするときはdc_mcf_sendsync関数【CBLDCMCF('SENDSYNC')】を使います。UAPがdc_mcf_sendsync関数を呼び出すと，MCFはメッセージを出力用のバッファ（メモリ上の出力キュー）に書き込んで，相手システムへ送信します。相手システムへのメッセージ送信が完了したことをMCFで確認したあと，dc_mcf_sendsync関数はリターンします。

同期型のメッセージ受信

相手システムからのメッセージを受信すると，MCFはメッセージを入力用のバッファに格納します。MHPでは，このメッセージを受け取るためにdc_mcf_recvsync関数【CBLDCMCF('RECVSYNC')】を呼び出します。

相手システムからのメッセージを受信していた場合は，dc_mcf_recvsync関数にメッセージを渡します。相手システムからのメッセージをまだ受信していない場合は，受信するまでdc_mcf_recvsync関数は待ち続けます。相手システムからメッセージを受信した時点で，dc_mcf_recvsync関数にメッセージを渡します。

同期型のメッセージ送受信

同期型のメッセージの送信と受信を一つの関数でする形態です。MHPは，dc_mcf_sendrecv関数【CBLDCMCF('SENDRECV')】でMCFにメッセージの送信要求をします。MCFはメッセージを出力キューに書き込んで，相手システムへ送信します。送信処理が完了したあとも，dc_mcf_sendrecv関数はリターンしないで，引き続き受信処理をします。受信までの処理が完了した時点でdc_mcf_sendrecv関数はリターンします。

(2)　同期型のメッセージ処理の時間監視

同期型のメッセージ処理で，無制限に応答を待ち続けるのを避けるため，監視時間を設定できます。この監視時間は，関数の引数watchtimeに設定します。0を設定した場合は，MCFマネジャ定義のUAP共通定義で指定した同期送受信監視時間が仮定されます。UAP共通定義の監視時間に0が指定されていた場合は，無制限に応答を待ち続けます。

同期型のメッセージの処理時間は，トランザクションブランチの限界経過時間に含めるか含めないかを選択できます。この指定はユーザサービス定義，ユーザサービスデフォルト定義，トランザクションサービス定義のtrn_expiration_time_suspendで指定します。なお，非トランザクション属性のMHPの限界経過時間に含めることはできません。trn_expiration_time_suspendに指定する値とトランザクションの時間監視の詳細については，マニュアル「OpenTP1 システム定義」を参照してください。

注意事項

監視時間の精度は秒単位です。また，タイマ定義（mcfttim -t）のbtimオペランドで指定する時間監視間隔でタイムアウトが発生したかどうかを監視しています。このため，設定した監視時間と実際にタイムアウトを検出する時間には秒単位の誤差が生じます。そのため，タイミングによっては，設定した監視時間よりも短い時間でタイムアウトすることがあります。監視時間が小さくなるほど，誤差の影響を受けやすくなりますので，監視時間は3（単位：秒）以上の値の設定を推奨します。

(3)　同期型のメッセージ処理とロールバック

MHPがロールバックされた場合，同期型のメッセージは廃棄されません。ただし，dc_mcf_sendsync関数，またはdc_mcf_sendrecv関数で複数セグメントを送信した場合に，最終セグメント（EMI）を指定しないでreturn()を呼び出したときは，メッセージは廃棄されます。

同期型のメッセージ処理を次の図に示します。

図3‒10　同期型のメッセージ処理

3.6.6　継続問い合わせ応答の処理

問い合わせ応答の処理を連続させることで，端末とUAPが交互にメッセージをやり取りする形態です。継続問い合わせ応答は，アプリケーションの型が継続問い合わせ応答型（cont型）のMHPでだけできます。

(1)　継続問い合わせ応答の処理概要

継続問い合わせ応答をするMHPでは，dc_mcf_receive関数を呼び出して，端末からのメッセージを受信します。処理後dc_mcf_reply関数で応答を返します。応答を返す場合，継続して処理するMHPを変更するときは，dc_mcf_reply関数に変更後のアプリケーション名を設定します。設定しないと，前回と同じMHPが起動されます。

さらに，継続問い合わせ応答処理中のMHPから，dc_mcf_execap関数でアプリケーション起動できます。ただし，即時起動だけできます。この場合，dc_mcf_execap関数で起動できるcont型のMHPは一つだけです。また，cont型のアプリケーションを起動したMHPでは，継続応答権が移動しているので，dc_mcf_reply関数は呼び出せません。また，dc_mcf_contend関数も呼び出せません。

継続問い合わせ応答の処理中でも，端末への一方送信メッセージ（dc_mcf_send関数）は送信できます。

(2)　一時記憶データへのアクセス

継続問い合わせ応答では，続けて起動するMHPへ処理を引き継ぐ情報として，一時記憶データを使えます。一時記憶データは論理端末対応に使えるので，複数の論理端末で，同時に一つのMHPを使って継続問い合わせ応答もできます。

一時記憶データ用の領域として更新用領域と回復用領域を共有メモリに確保します。一時記憶データ格納用領域の長さは，MHPごとに，MCFアプリケーション定義で指定します。

一時記憶データは，継続問い合わせ応答の場合にだけ使えます。そのほかのメッセージ通信形態では使えません。

(a)　一時記憶データの受け取り

MHPから一時記憶データを使う場合は，dc_mcf_tempget関数【CBLDCMCF('TEMPGET ')】を呼び出します。一時記憶データ格納用領域が初期状態である場合や，一時記憶データがないときは，MCFアプリケーション属性定義のtempsizeで指定した長さの（00）₁₆があるものと見なして，dc_mcf_tempget関数が実行されます。

dc_mcf_tempget関数に指定した受け取り領域長が，一時記憶データ長よりも小さい場合は，指定した長さ分だけ受け取って，超えた部分は切り捨てます。dc_mcf_tempget関数に指定した受け取り領域長が，一時記憶データ長よりも大きい場合は，一時記憶データだけを，受け取り領域に格納します。

(b)　一時記憶データの更新

一時記憶データを更新する場合は，dc_mcf_tempput関数【CBLDCMCF('TEMPPUT ')】を呼び出します。一時記憶データ格納用領域を更新すると，データそのものが入れ替わります。更新データ長は，MCFアプリケーション定義で指定した値を超える値は設定できません。

dc_mcf_tempput関数を呼び出す前には，dc_mcf_tempget関数を必ず呼び出しておきます。呼び出していない場合は，dc_mcf_tempput関数はエラーリターンします。

(3)　継続問い合わせ応答の終了

継続問い合わせ応答は，次のどれかの事象が実行されると終了します。継続問い合わせ応答処理が終了すると，それまで使っていた一時記憶データ格納用領域は削除されます。

MHPからdc_mcf_contend関数【CBLDCMCF('CONTEND ')】の呼び出し

mcftendctコマンドで論理端末名称を指定して強制終了

mcftendctコマンドは，継続問い合わせ応答の処理でないUAPからも，dc_adm_call_command関数で実行できます。mcftendctコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。

UAPの異常終了

継続問い合わせ応答処理をしたMHPで，dc_mcf_reply関数を呼び出さないで終了しても，異常終了します。

(4)　UAPの異常終了によるエラーイベント発生時の処置

継続問い合わせ応答処理中にUAPが異常終了した場合は，ERREVT3が通知されます。このERREVT3を処理するMCFイベント処理用MHPで，次に起動するアプリケーション名を設定したdc_mcf_reply関数を呼び出していれば，継続問い合わせ応答の処理を続けられます。呼び出していない場合は，継続問い合わせ応答の処理は終了します。

継続問い合わせ応答の概要を次の図に示します。

図3‒11　継続問い合わせ応答の概要

3.6.7　メッセージの再送

送信したメッセージを，再び送信できます。メッセージはdc_mcf_resend関数【CBLDCMCF('RESEND ')】で再送します。再送するメッセージは，以前に送信したメッセージとは別の，新しいメッセージとして扱います。次のような場合に，メッセージを再送します。

プリンタに送信したメッセージでの印字が鮮明でない，または文字が破壊されている場合

同じ帳票を複数枚必要な場合

表示していた画面が消えてしまった場合

(1)　再送できるメッセージの条件

再送の対象にできるのは，次のすべての条件を満たしているメッセージです。

メッセージ送信時に出力通番を付けていること

送信メッセージの割り当て先にディスクキューを指定する論理端末（mcftalcle -k quekindにdiskを指定）を使用していること

相手システムにメッセージが正常に送信されるなどにより，送信済みになっていること※1

送信済みのメッセージがディスクキューに保持されていること※2

注※1

UAPからメッセージを送信したあと，出力キューに滞留したままのメッセージは再送の対象にはなりません。また，-dオプションを省略したmcftdlqleコマンドの入力，またはdc_mcf_tdlqle関数で削除したメッセージは送信済みのメッセージと見なします。一方，-dオプションを指定したmcftdlqleコマンド，またはmcftspqleコマンドで削除したメッセージは，送信済みのメッセージと見なしません。

注※2

ディスクキューに保持できるメッセージ数については，「(3)　システムサービス定義との関連」を参照してください。

メッセージキュー（ディスクキュー）内に対象のメッセージがない場合，dc_mcf_resend関数はエラーリターンします。

(2)　再送対象メッセージの指定内容

どのメッセージを再送するかは，送信済みメッセージに設定してあった，次に示す情報で選択します。

出力先の論理端末名称

出力先の論理端末名称を指定することで，取り出すメッセージがある出力キューを決定します。

メッセージ出力通番

出力通番は，次のどちらかで設定します。メッセージを再送するときは，新しく出力通番を付け直せます。

再送対象メッセージの出力通番を設定

送信済みメッセージのうち，最終出力通番のメッセージを再送することを設定

メッセージ種別（一般分岐，または優先分岐）

メッセージを再送するときには，メッセージ種別を新しく指定し直せます。

(3)　システムサービス定義との関連

メッセージキュー（ディスクキュー）内に保持する送信済みメッセージ数はメッセージキューサービス定義のquegrpコマンドの-mオプションで指定します。

論理端末ごとにこのオプションで指定したメッセージ数をメッセージキューに保持することができます。

(4)　ネットワークコミュニケーション定義との関連

メッセージを再送するとき，MCFマネジャ定義のUAP共通定義（mcfmuap）の-eオプションで指定した最大セグメント長分の領域だけ，作業領域として使います。再送するメッセージセグメント長が，この作業領域よりも大きい場合は，dc_mcf_resend関数はエラーリターンします。このため，UAP共通定義の-eオプションでは，再送するメッセージの最大長以上の値を設定しておいてください。

また，MCFマネジャ定義のUAP共通定義（mcfmuap）の-lオプションでの，出力通番に関する指定内容によっては，メッセージキューファイル内に同じ出力通番を持ったメッセージが同時に存在する場合があります。この場合，どのメッセージを再送するか保証できません。

3.7　MCFのトランザクション制御

OpenTP1では，相手システムから受け取ったメッセージの処理をトランザクションとして処理できます。

ここでは，メッセージ送受信形態のUAP（MHP）のトランザクション制御について説明します。クライアント／サーバ形態のUAP（SUP，SPP）のトランザクション制御については，「2.3　トランザクション制御」を参照してください。

3.7.1　MHPのトランザクション制御

MHPは，OpenTP1のメッセージ受信によるMHPの開始から，MHPの終了まで，必ずトランザクションになります。つまり，MHPで扱う処理はすべてOpenTP1でトランザクションと見なして処理します。※

MHPのサービス関数では，トランザクション制御をする関数（dc_trn_begin関数など，dc_trnで始まる同期点取得の関数）は使えません。さらに，MHPからSPPのサービスを要求する場合，サービスを要求されたSPPでは，トランザクション制御をする関数は呼び出せません。MHPからSPPのサービスを要求するときは，そのSPPの処理でトランザクション制御をする関数を呼び出していないことを確認してください。

注※

MCFの拡張機能として，MHPの処理をトランザクションとしないこともできます。これを非トランザクション属性のMHPといいます。非トランザクション属性のMHPについては，「3.8.3　非トランザクション属性のMHP」を参照してください。

(1)　トランザクション属性の指定

MHPは，ユーザサービス定義でトランザクション属性である（atomic_update=Y）ことを指定しておきます。

(2)　関数を使った同期点取得

MHPの処理の中で，連鎖モードのコミットとして同期点を取得できます。同期点は，dc_mcf_commit関数【CBLDCMCF('COMMIT ')】で取得します。dc_mcf_commit関数が正常に終了すると，続くMHPの処理は新しいグローバルトランザクションとなります。

MHPから始まるグローバルトランザクションが，複数のトランザクションブランチから構成される場合（MHPからdc_rpc_call関数でSPPを呼び出しているとき）は，それぞれのトランザクションブランチの処理結果がコミットとならないかぎりコミットとなりません。コミットできない場合は，すべてのトランザクションブランチがロールバックされます。

メッセージを受信する前に，dc_mcf_commit関数で同期点を取得できません。また，dc_mcf_commit関数で同期点を取得したあとで，そのMHPでメッセージを受信できません。

dc_mcf_commit関数で同期点取得の対象となるメッセージ処理は，非同期のメッセージとアプリケーションプログラムの起動です。同期型のメッセージ送受信の処理は，同期点取得の対象にはなりません。

dc_mcf_commit関数は，MCFアプリケーション定義で非応答型（noans型）を指定したMHPからだけ呼び出せます。それ以外の型のMHPで呼び出した場合は，エラーリターンします。また，MHP以外のUAPでは，dc_mcf_commit関数は呼び出せません。

(3)　MHPのロールバック処理

(a)　MHPの処理が異常終了した場合

MHPが異常終了またはロールバック※1した場合は，エラーイベントが通知されます。dc_mcf_receive関数が先頭セグメントを受け取ったかどうかで，通知されるエラーイベントは異なります。

先頭セグメントを受け取る前に異常終了した場合：ERREVT2※2

先頭セグメントを受け取ってから異常終了した場合：ERREVT3

注※1

MCFアプリケーション定義（mcfaalcap -g）のrecvmsgオペランドにrを指定した場合，またはdc_mcf_rollback関数のactionにDCMCFRTRYもしくはDCMCFRRTNを指定した場合は除きます。

注※2

非常駐MHPの場合，次のような原因でMHPが起動できないときは，ERREVT2は通知されません。

該当するロードモジュールが存在しない。

RPCインタフェース定義ファイルに記載したエントリポイントに対応したサービス関数がない。

このとき，該当するサービスグループの入力キューのスケジュールを閉塞し，受信メッセージを入力キューに残します。

(b)　MHPの処理中にエラーが起こった場合

MHPのトランザクション処理がエラーとなったときは，メッセージを受信する前の状態に戻すため，ロールバック（dc_mcf_rollback関数【CBLDCMCF('ROLLBACK')】）をMHPで呼び出してください。メッセージを受け取ったMHPがロールバックしたときに，再びOpenTP1でMHPをスケジュールし直すかどうかは，dc_mcf_rollback関数の引数の指定に従います。

NORETURN（actionにDCMCFNRTN）を設定した場合

ロールバックしたあとで，MHPに制御を戻しません。該当のMHPは異常終了して，ERREVT3が通知されます。

RETURN（actionにDCMCFRRTN）を設定した場合

正常にロールバックできた場合，dc_mcf_rollback関数が正常に終了します。そのあとで，MHPで任意の処理を続けられます。ロールバックしたあとは新しい別のトランザクションとなります。

RETRY（actionにDCMCFRTRY）を設定した場合

dc_mcf_rollback関数がリターンしないで，いったんMHPのプロセスを終了します。ロールバックしたあとでMHPをスケジュールし直します。この値を設定するdc_mcf_rollback関数を使う場合は，そのノードにアプリケーション起動プロセスが必要になります。

メッセージ送受信形態の処理とトランザクションの関係を次の図に示します。

図3‒12　メッセージ送受信形態の処理とトランザクションの関係

（説明）

メッセージを受信した時点で，MHPから始まる処理はグローバルトランザクションになります。

MHPのトランザクション処理でエラーが起こった場合は，ロールバック（部分回復）してから，MCFに制御を渡します。リターン指定（actionにDCMCFRRTNを設定）のdc_mcf_rollback関数を呼び出すと，新しいトランザクションの処理もできます。

(4)　メッセージ送受信関数がエラーリターンしてもMHPがコミットとなる場合

MHPの処理で，メッセージ送受信機能の関数がエラーリターンしたあとで，リターンで処理を終了させた場合，そのトランザクション自体はコミットすることがあります。このようなMHPの処理の中でリソースマネジャ（RM）にアクセス（DAM，TAM）をしていれば，このアクセスの処理はコミットになります。アクセスの処理もロールバックとしたい場合は，エラーリターン後にdc_mcf_rollback関数を呼び出す処理を作成しておくか，abortを呼び出しておいてください。

(5)　MHPからトランザクションを開始する関数を呼び出す場合

MHPでも，サービス関数の処理範囲以外（メイン関数の処理範囲）ならば，トランザクションの開始（dc_trn_begin関数）を使えます。トランザクションの開始と同期点取得は，メイン関数のdc_rpc_open関数からdc_mcf_mainloop関数の間，またはdc_mcf_mainloop関数からdc_rpc_close関数の間で呼び出せます。

MHPのメイン関数でdc_trn_begin関数を呼び出したときは，そのメイン関数で必ず非連鎖モードのコミット（dc_trn_unchained_commit関数）を呼び出して同期点を取得してください。

3.8　MCFの拡張機能

MCFには，メッセージ送受信以外にも次に示す機能があります。

アプリケーションプログラムの起動

コマンドを使ったMHPの起動

非トランザクション属性のMHP

ユーザタイマ監視機能による時間監視

3.8.1　アプリケーションプログラムの起動

MHPまたはSPPから，MHPを起動できます。アプリケーションプログラムを起動する関数（dc_mcf_execap関数【CBLDCMCF('EXECAP ')】）に，起動させたいMHPのアプリケーション名と，引き渡すメッセージのセグメントを設定します。

(1)　アプリケーションプログラムを起動するときに使用するMCFのプロセス

アプリケーション起動機能（dc_mcf_execap関数）を使う場合，メッセージ送受信の関数（dc_mcf_receive関数，dc_mcf_send関数など）とは別のMCFのプロセスを使います。メッセージ送受信で使うMCFのプロセスをMCF通信プロセス，dc_mcf_execap関数で使うMCFのプロセスをアプリケーション起動プロセスといいます。アプリケーション起動プロセスは，通信プロトコルには依存しません。

(2)　アプリケーションプログラムを起動する方法

dc_mcf_execap関数でアプリケーションプログラムを起動できるのは，MHPとSPPです。dc_mcf_execap関数を呼び出すと，MHPを起動できます。

dc_mcf_execap関数で送信したセグメントは，MHPで呼び出すdc_mcf_receive関数で受け取ります。起動できるのは，dc_mcf_execap関数を呼び出したUAPと同じノードにあるMHPだけです。他ノードのMHPは，dc_mcf_execap関数で起動できません。※

注※

TP1/NET/OSAS-NIFを使用して通信する場合は，dc_mcf_execap関数でメッセージ送受信をするので，この限りではありません。

(3)　起動するタイミング

起動させるMHPが実際に起動するのは，次の場合です。

MHPからdc_mcf_execap関数を呼び出した場合

MHPのトランザクションがコミット（MHPが正常に終了，またはdc_mcf_commit関数が正常に終了）してから，起動します。

SPPからdc_mcf_execap関数を呼び出した場合

トランザクションがコミットとなったときに，起動します。

SPPからdc_mcf_execap関数を呼び出す場合は，SPPがトランザクションとして処理していることと，そのSPPのメイン関数でdc_mcf_open関数を呼び出していることが前提です。

(4)　アプリケーションプログラムの起動の種類

MHPを起動する方法は，次の2種類があります。

(a)　即時起動

dc_mcf_execap関数を呼び出したUAPの処理がコミットとなってから，すぐに起動します。

(b)　タイマ起動

dc_mcf_execap関数を呼び出した直後から，設定した時間に起動します。タイマ起動には，次の2とおりの指定があります。

経過時間指定のタイマ起動

dc_mcf_execap関数を呼び出した直後から，設定した秒数が過ぎてから起動します。設定した秒数が過ぎてもdc_mcf_execap関数を呼び出したUAPの処理がコミットしていない場合は，コミットを待ってからすぐに起動します。

注意事項

時間監視の精度は秒単位です。また，タイマ定義（mcfttim -t）のbtimオペランドで指定する時間監視間隔で起動するかどうかを監視しています。このため，設定した経過時間と実際に起動する時間には秒単位の誤差が生じます。そのため，タイミングによっては，設定した監視時間よりも短い時間で起動することがあります。監視時間が小さくなるほど，誤差の影響を受けやすくなりますので，監視時間は3（単位：秒）以上の値の設定を推奨します。

時刻指定のタイマ起動

dc_mcf_execap関数を呼び出したあと，設定した時刻になったときに起動します。dc_mcf_execap関数を呼び出した時刻が，関数に設定した時刻を過ぎていた場合に，その場で即時に起動するか，翌日の指定時刻まで持ち越すかを指定します。この指定は，MCFマネジャ定義UAP共通定義に指定します。

アプリケーション起動機能を使用する場合，起動要求を行ってからUAPの開始時刻までの間に夏時間と標準時間の移行が生じたときは，起動要求した時間帯の時刻でUAPが起動されます。

注意事項

時間監視の精度は秒単位です。また，タイマ定義（mcfttim -t）のbtimオペランドで指定する時間監視間隔で起動するかどうかを監視しています。このため，設定した時刻と実際に起動する時刻には秒単位の誤差が生じます。

(5)　アプリケーションプログラムの起動前に障害が起こった場合のエラーイベント

dc_mcf_execap関数を呼び出して，MHPを起動するまでに障害が起こった場合は，次のMCFイベントが通知されます。

即時起動の場合：ERREVT2

タイマ起動の場合：ERREVT4

MCFイベントについては，「3.10　MCFイベント」を参照してください。

アプリケーションプログラムの起動を次の図に示します。

図3‒13　アプリケーションプログラムの起動

(6)　システム定義との関連

(a)　MCF通信構成定義との関係

dc_mcf_execap関数を呼び出すUAPがあるノードには，通常の実行プロセスのほかに，アプリケーション起動プロセスが必要になります。アプリケーション起動プロセスはMCF通信構成定義で定義します。アプリケーションプログラムを起動させる関数を使うOpenTP1では，MCF通信構成定義のアプリケーション起動定義を作成しておいてください。

アプリケーション起動定義では，アプリケーション起動環境定義（mcftpsvr）で内部通信路を定義し，アプリケーション起動用論理端末定義（mcftalcle）で論理端末を定義します。

内部通信路や論理端末は複数のアプリケーションで共用できるので，1対1で対応づける必要はありません。

(b)　MCFアプリケーション定義との関係

MCFアプリケーション定義のアプリケーション属性定義（mcfaalcap）のtypeオペランドに指定したアプリケーションの型によって，アプリケーション起動の使い方が決まります。

応答型（ans型）のアプリケーションを起動させる場合

応答メッセージを送信できるMHPは，応答型（ans型）を指定した場合だけです。問い合わせメッセージを受信したMHPからans型のアプリケーションを起動した場合は，応答権が移動します。そのため，ans型のアプリケーションは一度だけしか起動できません。さらに，いったんans型のアプリケーションを起動させたMHPからは，応答メッセージは送信できません。また，応答メッセージをすでに送信したMHPからは，ans型のアプリケーションを起動できません。

SPPからans型のアプリケーションを起動できません。

非応答型（noans型）のアプリケーションを起動させる場合

noans型のアプリケーションは，一つのトランザクションから複数回起動させることができます。

継続問い合わせ応答型（cont型）のアプリケーションを起動させる場合

cont型のアプリケーションを起動できるのは，継続問い合わせ応答処理中のMHPだけです。この場合，即時起動だけで，タイマ起動はできません。継続問い合わせ応答処理中のMHPからdc_mcf_execap関数を呼び出す場合，アプリケーション起動できるcont型のアプリケーションは一つだけです。また，cont型のアプリケーションを起動したMHPでは，継続応答権が移動しているので，dc_mcf_reply関数は呼び出せません。また，dc_mcf_contend関数も呼び出せません。

SPPからcont型のアプリケーションを起動できません。

(c)　MCFマネジャ定義との関係

アプリケーションを起動する順序をUAPからの関数の呼び出し順にするか，トランザクションのコミット順にするかは，MCFマネジャ定義のUAP共通定義（mcfmuap -c）のorderオペランドで指定します。

トランザクションのコミットに時間が掛かった場合，同じ論理端末を使用するほかのアプリケーションの起動を待ち合わせるため，起動順序は，トランザクションのコミット順（commitを指定）を推奨します。

(d)　UAPとアプリケーション起動プロセスとの関連づけ

dc_mcf_execap関数を呼び出すUAPとアプリケーション起動プロセス間で定義する内容を関連づける必要があります。

UAPとアプリケーション起動プロセスとの関連づけを以降の図に示します。

MHPから非応答型のアプリケーションを起動させる場合

図3‒14　MHPから非応答型のアプリケーションを起動する場合の関連づけ

アプリケーション起動プロセスのアプリケーション環境定義のアプリケーション起動識別子（mcfaenv -p）に，MCF環境定義のアプリケーション起動識別子（mcftenv -s）を指定します。

アプリケーション起動プロセスのアプリケーション属性定義の論理端末名称（mcfaalcap -n lname）に，アプリケーション起動用論理端末定義の論理端末名称（mcftalcle -l）を指定します。

MHPから応答型または継続問い合わせ応答型のアプリケーションを起動させる場合

図3‒15　MHPから応答型または継続問い合わせ応答型のアプリケーションを起動する場合の関連づけ

アプリケーション起動プロセスのアプリケーション環境定義のアプリケーション起動識別子（mcfaenv -p）に，MCF環境定義のアプリケーション起動識別子（mcftenv -s）を指定します。

アプリケーション起動プロセスのアプリケーション属性定義の内部通信路名（mcfaalcap -n cname）に，アプリケーション起動環境定義の内部通信路名（mcftpsvr -c）を指定します。

SPPから非応答型のアプリケーションを起動させる場合

図3‒16　SPPから非応答型のアプリケーションを起動する場合の関連づけ

ユーザサービス定義のMCFマネジャ識別子（mcf_mgridオペランド）に，MCF環境定義のMCFマネジャプロセス識別子（mcftenv -m）を指定します。

アプリケーション起動プロセスのアプリケーション環境定義のアプリケーション起動識別子（mcfaenv -p）とユーザサービス定義のアプリケーション起動識別子（mcf_psv_idオペランド）に，MCF環境定義のアプリケーション起動識別子（mcftenv -s）を指定します。

アプリケーション起動プロセスのアプリケーション属性定義の論理端末名称（mcfaalcap -n lname）に，アプリケーション起動用論理端末定義の論理端末名称（mcftalcle -l）を指定します。

(7)　起動させるMHPに渡す，入力元論理端末名称

MHPからdc_mcf_execap関数でMHPを起動する場合，起動されたMHPで受け取るメッセージ入力元の論理端末名称は，最初に受信したメッセージ中の名称になります。さらに，そのMHPからdc_mcf_execap関数を呼び出した場合も，受け取るメッセージ入力元の論理端末名称は，最初にメッセージを受信したときの名称が引き渡されます。

SPPからdc_mcf_execap関数でMHPを起動する場合，起動されたMHPで受け取るメッセージ入力元の論理端末名称は「＊」となります。さらに，そのMHPからdc_mcf_execap関数を呼び出した場合も，受け取るメッセージ入力元の論理端末名称は，「＊」となります。

アプリケーションプログラムの起動形態とtypeオペランドの指定を以降の図で示します。

図3‒17　一方送信メッセージを受信したMHPからの起動

図3‒18　問い合わせ応答メッセージを受信したMHPからの起動

図3‒19　問い合わせ応答メッセージの処理のMHPから，一方送信メッセージを送信するMHPの起動

図3‒20　トランザクション処理のSPPからの起動

(8)　TP1/Message Control（MCF）の再開始（リラン）時のタイマ起動の扱い

タイマ起動の時間待ちの間に障害が起こって，OpenTP1を再開始（リラン）した場合の扱いについて説明します。再開始（リラン）後にタイマ起動を引き継げるのは，ディスクキューを使っている場合だけです。再開始（リラン）した場合にタイマ起動をするdc_mcf_execap関数の扱いは次のとおりです。

(a)　タイマ起動の引き継ぎの定義

MCF通信構成定義mcftpsvr定義コマンドの-oオプションにreruntm=yesと指定した場合は，再開始（リラン）する前のタイマ起動メッセージを引き継ぎます。dc_mcf_execap関数に設定した時間を過ぎていた場合は，即時起動で引き継ぎます。時間を過ぎていない場合は，時間が来るまで待ってから起動します。

reruntm=noと指定した場合は，再開始（リラン）後にはタイマ起動を引き継ぎません。この場合は，もう一度UAPからタイマ起動のdc_mcf_execap関数を呼び出してください。

(b)　UOCでタイマ起動を引き継ぐ条件の変更

タイマ起動を引き継ぐ場合，UOCでタイマ起動を引き継ぐ条件を変更できます。このUOCをタイマ起動引き継ぎ決定UOCといいます。タイマ起動引き継ぎ決定UOCを使う場合は，MCF通信構成定義mcftpsvr定義コマンドの-oオプションにreruntm=yesと指定しておいてください。

タイマ起動引き継ぎ決定UOCについては，「3.9.2　タイマ起動引き継ぎ決定UOC」を参照してください。

3.8.2　コマンドを使ったMHPの起動

OpenTP1のコマンド（mcfuevtコマンド）を入力して，MHPを起動できます。メッセージ受信を契機に起動するMHPでも，mcfuevtコマンドで直接MHPを起動して，他システムへメッセージを送信できるようになります。

起動できるMHPは，非応答型（noans型）だけです。mcfuevtコマンドで起動するMHPには，noans型を指定してください。

(1)　コマンドで起動するMHPの定義

mcfuevtコマンドで起動するMHPのアプリケーション名は，UCMDEVTとします。MCFアプリケーション定義アプリケーション属性定義mcfaalcapの-nオプションには，次の値を指定しておきます。

nameオペランド：UCMDEVT

kindオペランド：user（または省略）

typeオペランド：noans（または省略）

(2)　MHPの起動方法

MHPを起動するときは，mcfuevtコマンドを実行します。mcfuevtコマンドの引数には，MCF通信プロセス識別子とMHPに渡す入力メッセージを指定します。

UCMDEVTを定義していない場合にmcfuevtコマンドを実行したときは，mcfuevtコマンドはエラーリターンします。このとき，ERREVT1は通知されません。

コマンドで起動するMHPは通信プロトコルに依存しないので，mcfuevtコマンドに指定するMCFのプロセスには，アプリケーション起動プロセスを指定することをお勧めします。

(3)　コマンドで起動したMHPの入力元論理端末名称とコネクション名

コマンドで起動したMHPの入力元論理端末名称は「@UCEVxxx」（xxxは，MCFプロセス識別子）となります。この入力元論理端末名称に対して，UAPからメッセージを送信すると，その関数はエラーリターンします。

コネクション名は「********」となります。

コマンドによるMHPの起動を次の図に示します。

図3‒21　コマンドによるMHPの起動

3.8.3　非トランザクション属性のMHP

トランザクションとして稼働しないMHP（非トランザクション属性のMHP）を作成できます。非トランザクション属性のMHPはトランザクションとして処理できませんが，従来のMHPの処理に比べて，処理速度を向上できます。

(1)　トランザクション処理のMHPとの違い

トランザクションとして稼働するMHPと同様のメッセージ送受信の関数を使えます。ただし，次の点が異なります。

メッセージ出力通番は設定できますが，エラー時の回復対象として出力通番を使えません。

同期点処理をする関数（dc_mcf_commit関数，dc_mcf_rollback関数）は呼び出せません。また，メッセージの再送（dc_mcf_resend関数）も呼び出せません。このような関数を呼び出した場合はエラーリターンします。

(2)　非トランザクション属性のMHPの定義

(a)　使えるメッセージキュー

非トランザクション属性のMHPでは，メモリキューだけ使えます。ディスクキューは使えません。MCFアプリケーション定義アプリケーション属性定義mcfaalcapの-gオプションquekindオペランドには，メモリキューを指定してください。

(b)　MHPのトランザクション属性

非トランザクション属性のMHPには，MCFアプリケーション定義アプリケーション属性定義のtrnmodeオペランドにnontrnを指定します。ユーザサービス定義のatomic_updateの値がYでも，トランザクションでない処理となります。

(c)　時間監視

非トランザクション属性のMHPの時間監視は，MCFアプリケーション定義アプリケーション属性定義mcfaalcapオペランドの-vオプションで指定します。ここに指定した時間を過ぎると，非トランザクション属性のMHPは異常終了します。この定義に0を指定した場合は，時間監視はしません。

非トランザクション属性のMHPから同期型のメッセージ通信関数を呼び出した場合，この処理時間は監視時間に含みません。非トランザクション属性のMHPからSPPのサービスを要求した場合は，SPPの処理時間も監視時間に含みます（このSPPで同期型のメッセージを処理している場合，その時間も監視時間に含みます）。

注意事項

サービス関数開始から終了までの実行監視時間の精度は秒単位です。そのため，タイミングによっては，指定した監視時間よりも短い時間でプロセスを強制停止することがあります。サービス関数開始から終了までの実行監視時間が小さくなるほど，誤差の影響を受けやすくなりますので，このオペランドには3（単位：秒）以上の値の指定を推奨します。

(3)　非トランザクション属性のMHPで障害が起こった場合

MCFアプリケーション定義の指定によって，ERREVT2，またはERREVT3のMCFイベント処理用MHPが起動されます。非トランザクション属性のMHPからSPPのサービスを要求している場合，SPPの処理に対しては何もしません。

継続問い合わせ応答形態の処理の場合に，一時記憶データの実更新ができなかったときは，エラーイベントの定義に関係なく，継続問い合わせ応答処理を終了させます。システム内部の障害などで，継続問い合わせ応答処理を終了できない場合は，継続問い合わせ応答の強制終了コマンド（mcftendct -f）の実行を要求するメッセージログが出力されるので，コマンドを実行して継続問い合わせ応答処理を終了させてください。

3.8.4　ユーザタイマ監視機能による時間監視

MHPまたはSPPから関数で時間監視を設定したり，その設定を取り消したりできます。この機能をユーザタイマ監視機能といいます。これによって，ユーザで任意の時間監視ができます。ユーザタイマ監視機能を使用するには，MCF通信構成定義mcfttimの-pオプションにusertime=yesを指定する必要があります。

ユーザタイマ監視を設定するにはdc_mcf_timer_set関数【CBLDCMCF('TIMERSET')】を呼び出し，ユーザタイマ監視を取り消すにはdc_mcf_timer_cancel関数【CBLDCMCF('TIMERCAN')】を呼び出します。ユーザタイマ監視の設定および取り消しは，トランザクションに関係なく，関数呼び出し時点で処理されます。

タイムアウトが発生したかどうかは，MCFが一定の時間監視間隔で行います。時間監視間隔はMCF通信構成定義mcfttimの-tオプションのbtimオペランドで指定します。

タイムアウトが発生した場合，dc_mcf_timer_set関数の引数に指定したMHPを起動させます。dc_mcf_timer_set関数の引数にユーザデータを指定しておくと，タイムアウトが発生した場合に起動させるMHPに，そのデータをメッセージとして渡せます。

なお，mcftlsutmコマンドを使用すると，ユーザタイマ監視の状態を表示できます。mcftlsutmコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。

ユーザタイマ監視機能はすべてのプロトコルで使用できます。

(1)　使用例

相手システムからの応答の時間監視を例に，ユーザタイマ監視機能の使用例を次の図に示します。

図3‒22　ユーザタイマ監視機能の使用例

(2)　ユーザタイマ監視機能を使用する場合の注意事項

ユーザタイマ監視の設定および取り消しは，関数呼び出し時点で処理されます。そのため，該当するトランザクションがロールバックしても，ユーザタイマ監視の設定および取り消し処理が無効となることはありません。

タイムアウト発生時に起動させるMHPは，非応答型（noans型）のMHPでなくてはなりません。MHPまたはSPPからdc_mcf_timer_set関数を呼び出してユーザタイマ監視を設定する場合に，引数に指定したMHPが非応答型でないときは，dc_mcf_timer_set関数がエラーリターンします。

時間監視の精度は秒単位です。また，タイマ定義（mcfttim -t）のbtimオペランドで指定する時間監視間隔でタイムアウトが発生したかどうかを監視しています。このため，設定した監視時間と実際にタイムアウトを検出する時間には秒単位の誤差が生じます。そのため，タイミングによっては，設定した監視時間よりも短い時間で起動することがあります。監視時間が小さくなるほど，誤差の影響を受けやすくなりますので，監視時間は3（単位：秒）以上の値の設定を推奨します。

タイムアウト発生によってMHPが起動される直前に，dc_mcf_timer_cancel関数が呼び出されると，この関数が「タイムアウト発生済み」でエラーリターンしたあとに，該当するMHPが起動されることがあります。

ユーザタイマ監視機能使用時にタイムアウトが頻発すると，通常のメッセージ制御処理の性能に影響します。タイムアウト発生によってアプリケーションを起動させることを，正常時の処理とする使い方はしないでください。

ユーザタイマ監視の要求数の最大値を通信構成定義mcfttimの-pオプションのtimereqnoオペランドに指定しておく必要があります。このオペランドで指定した値によって，MCFは事前に要求数分の監視用テーブルを静的共用メモリ上に確保します。1件の設定に対して「約100バイト+ユーザデータサイズ」の静的共用メモリが必要です。すべてのMCFでの静的共用メモリの合計値を，MCFマネジャ定義mcfmcomnの-pオプション，およびシステム環境定義のstatic_shmpool_sizeオペランドの指定値に加算してください。

システムダウン時に時間監視中であった場合，再開始（リラン）時に無効となります。ただし，入力キューにディスクキューを使用した場合，タイムアウト発生によってMHPを起動する直前で，システムダウンした場合，再開始後にMHPを起動する可能性があります。したがって，入力キューにはメモリキューを使用することをお勧めします。

3.9　ユーザオウンコーディング（UOC）

OpenTP1でメッセージ送受信形態の通信をする場合に，UAPのメッセージ処理を補助するために作成するプログラムをユーザオウンコーディング（UOC　User Own Coding）といいます。UOCは，業務に合わせて任意に作成してください。

UOCのコーディングには，C言語またはC++言語を使います。C言語の場合は，ANSI Cの形式またはANSI準拠前のK&Rの形式のどちらかに従ってコーディングします。C++言語の場合は，C++言語の仕様でコーディングします。

メッセージ送受信の処理とユーザオウンコーディングの位置を次の図に示します。

図3‒23　メッセージの送受信の処理とユーザオウンコーディングの位置

OpenTP1で使えるユーザオウンコーディング

OpenTP1で使えるUOCの一覧を次の表に示します。

表3‒12　OpenTP1で使えるユーザオウンコーディング

UOCの種類

UOCでできる処理

UOCを使わないときの処理

入力メッセージの編集，

アプリケーション名決定UOC

受信したメッセージを編集します。

メッセージを処理するMHPのアプリケーション名を決定します。

先頭セグメントの，最初の空白までの先頭8文字をアプリケーション名とします。

送信メッセージの通番編集UOC

送信するセグメントに出力通番を付けます。

メッセージを編集しないで出力キューに書き込みます。

タイマ起動引き継ぎ決定UOC

再開始（リラン）後のタイマ起動のアプリケーション起動機能の条件を変更できます。

定義の指定によって，引き継ぐかどうかが決まります。

出力メッセージの編集UOC

出力するメッセージを編集します。

出力するメッセージを編集しないで送信します。

この表に示すUOCは，MCFで使う通信プロトコル対応製品によって文法が異なります。また，この表に示すUOC以外にも，通信プロトコル対応製品で固有のUOCが使える場合があります。UOCの文法については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

この表に示すUOCのうち，タイマ起動引き継ぎ決定UOCは通信プロトコル対応製品に依存しないUOCです。タイマ起動引き継ぎ決定UOCの文法については，マニュアル「OpenTP1 プログラム作成リファレンス C言語編」を参照してください。

3.9.1　入力メッセージの編集UOC，アプリケーション名決定UOC

入力メッセージの内容を処理するMHPを決めるアプリケーション名を決定するUOCです。このUOCを組み込んだ場合，OpenTP1で他システムからのメッセージを受け取ると，最初にこのUOCに渡されます。UOCの処理が終了すると，メッセージのデータは入力キューに渡ります。そして，OpenTP1でスケジュールされたMHPのメッセージの受信をする関数に渡されます。

MCFイベントが通知された場合に，MCFイベント処理用MHPで回復処理をするときは，入力メッセージの編集とアプリケーション名決定UOCは経由しません。

入力メッセージの編集とアプリケーション名決定UOCの形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

(1)　OpenTP1への組み込み方法

MCFメイン関数（スタート関数　dc_mcf_svstart関数）に，作成したUOCの関数アドレスを指定します。入力メッセージの編集UOCの関数アドレスは任意に決められます。UOCのオブジェクトファイルは，MCFメイン関数を翻訳・結合すれば，MHPの実行形式ファイルに結合されて実行できる状態になります。MCFメイン関数については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.9.2　タイマ起動引き継ぎ決定UOC

タイマ起動のdc_mcf_execap関数を呼び出したあとで，障害が起こってOpenTP1を再開始（リラン）した場合，タイマ起動の環境を変更するUOCです。タイマ起動引き継ぎ決定UOCを作成しておくと，次に示すことができます。

タイマ起動を引き継ぐ，または取り消す。

引き継いだタイマ起動を即時起動とする。

起動するアプリケーション名を変更する。

(1)　OpenTP1への組み込み方法

アプリケーション起動サービス用のMCFメイン関数（dc_mcf_svstart関数）に作成したUOCの関数アドレスを指定します。関数アドレスは任意です。UOCのオブジェクトファイルは，MCFメイン関数を翻訳・結合すれば，アプリケーション起動サービスの実行形式ファイルに結合されて実行できる状態になります。アプリケーション起動サービス用のMCFメイン関数については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.9.3　送信メッセージの通番編集UOC

送信メッセージに出力通番を付けるUOCです。MHPからメッセージを送信する関数の指定で起動するUOCです。

送信メッセージの通番編集UOCは，send_uoc関数として作成します。ただし，送信メッセージの通番編集UOCはメッセージを送信する関数の最初のセグメントを送信するときに起動するので，このUOCでは第1セグメントだけしか編集できません。

送信メッセージの通番編集UOCの形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

(1)　OpenTP1への組み込み方法

MHPのメイン関数の中に，dc_mcf_regster関数として登録します。

3.9.4　出力メッセージの編集UOC

応答メッセージ，または一方送信メッセージの編集をするUOCです。出力メッセージの編集UOCは，UAPが送信したメッセージを他システムに実際に送信する前に処理するように位置させます。

出力メッセージの編集UOCの形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

(1)　OpenTP1への組み込み方法

入力メッセージの編集とアプリケーション名決定UOCと同じように，MCFメイン関数で呼び出すスタート関数に関数アドレス名を指定します。出力メッセージの編集UOCの関数アドレスは任意に決められます。MCFメイン関数については，マニュアル「OpenTP1 運用と操作」を参照してください。

3.10　MCFイベント

メッセージ送受信形態の通信をする場合，OpenTP1の各種システム情報をMHPに知らせるために，MCFからメッセージを出力します。これをMCFイベントといいます。メッセージ送受信の処理でエラーや障害が起こった場合，システム内で何が起こっているのかがMCFイベントの内容でわかります。MCFイベントには，エラーや障害発生などのエラーイベントと，コネクションの確立・解放などプロトコルに依存する通信イベントの2種類があります。

MCFイベントの内容を基に障害の対処をするMHPをMCFイベント処理用MHPといいます。このMHPを作成しておくと，独自の障害回復処理などができます。

MCFイベントは入力キューに渡されて，MCFイベント処理用MHPが起動されます。このとき，入力メッセージの編集とアプリケーション名決定UOCは経由しません。また，MCFイベントに対して障害が起こったことによって，MCFイベントが起動されることはありません。

MCFイベントの一覧を次の表に示します。次の表に示すMCFイベント以外にも，通信プロトコル対応製品で固有なMCFイベントが通知される場合があります。通信プロトコル対応製品で固有なMCFイベントについては，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

表3‒13　MCFイベントの一覧

MCFイベント名

MCFイベントコード

MCFイベントが通知された原因

MCFイベント処理用

MHPで実行する処理の例

不正アプリケーション名検出通知イベント

ERREVT1

メッセージのアプリケーション名がMCFアプリケーション定義にありません。

該当するアプリケーション名がなかったことを知らせます。

受信したメッセージが問い合わせメッセージの場合は，応答メッセージを送信できます。

メッセージ廃棄通知イベント

ERREVT2

次に示す理由で，MCFで受信した入力キューのメッセージ，またはアプリケーションの即時起動によって入力キューに入力されたメッセージを廃棄しました。

入力キューに障害が発生しました。

入力メッセージ最大格納数を超過しました。

動的共用メモリが不足しました。

キューファイルが満杯になりました。

MHPのサービス，サービスグループ，またはアプリケーションが閉塞しています。

スケジュール閉塞されているサービスグループの入力キューに未処理受信メッセージが残った状態で，OpenTP1を正常終了または計画停止Aで終了しました。

MHPのサービスグループ，またはアプリケーションがセキュア状態です。

MHPで呼び出すdc_mcf_receive関数にセグメントを渡す前に，MHPが異常終了しました。

アプリケーション名に相当するMHPのサービスがありません。

ユーザサーバ未起動などによって，MHPの起動に失敗しました。

DBMSの障害などによって，トランザクションの開始に失敗しました。

メッセージを廃棄したことを知らせます。

受信したメッセージが問い合わせメッセージの場合は，応答メッセージを送信できます。

UAP異常終了通知イベント

ERREVT3

MHPで呼び出すdc_mcf_receive関数にセグメントを渡したあとで，MHPが異常終了，またはロールバック※しました。

UAPが異常終了，またはロールバックしたことを知らせます。

受信したメッセージが問い合わせメッセージの場合は，応答メッセージを送信できます。

タイマ起動メッセージ廃棄通知イベント

ERREVT4

タイマ起動のアプリケーション起動によって入力キューに入力されたメッセージをERREVT2に示す理由で廃棄しました。

メッセージを廃棄したことを知らせます。

受信したメッセージが問い合わせメッセージの場合は，応答メッセージを送信できます。

未処理送信メッセージ廃棄通知イベント

ERREVTA

次に示す理由で，UAPから送信した未処理送信メッセージを廃棄しました。

MCFの正常終了処理時に，未処理送信メッセージの滞留時間監視の時間切れ（タイムアウト）が起こりました。

mcftdlqleコマンドまたはdc_mcf_tdlqle関数で，出力キューが削除されました。

タイマ起動要求や閉塞されている論理端末の出力キューに未処理送信メッセージが残った状態で，dcstopコマンドが実行されました。

未処理送信メッセージを廃棄したことを知らせます。

受信した未処理送信メッセージは，任意のファイルへ退避します。

送信障害通知イベント

SERREVT

メッセージを送信する途中で，通信プロトコルの障害が起こりました。

通信プロトコルの障害でメッセージを送信できなかったことを知らせます。

送信完了通知イベント

SCMPEVT

相手システムへ，メッセージを正常に送信できました。

相手システムまでメッセージを正常に送信できたことを知らせます。

障害通知イベント

CERREVT

（VERREVT）

通信管理プログラムで，コネクション障害，または論理端末障害が起こりました。コネクション確立再試行を定義している場合は，通知されません。

コネクション，または論理端末に障害が起こったことを知らせます。

状態通知イベント

COPNEVT

（VOPNEVT）

コネクションが確立しました。

メッセージを送受信できることを知らせます。

CCLSEVT

（VCLSEVT）

コネクションが正常に解放されました。

メッセージを送受信できないことを知らせます。

注

ERREVT1，ERREVT2，ERREVT3，ERREVT4，ERREVTAはエラーイベントを示します。

SERREVT，SCMPEVT，CERREVT，COPNEVT，CCLSEVTは通信イベントを示します。

注※

MCFアプリケーション定義（mcfaalcap -g）のrecvmsgオペランドにrを指定した場合，またはdc_mcf_rollback関数のactionにDCMCFRTRYもしくはDCMCFRRTNを指定した場合は除きます。

MCFイベント処理用MHPのアプリケーションの型

MCFイベント処理用MHPのアプリケーションの型は，MCFイベントが通知された原因で決まります。MCFイベント処理用MHPでは，決められたアプリケーションの型に応じた処理をしてください。

ERREVT1，ERREVT2，およびERREVT3のMCFイベント処理用MHPを起動する場合には，アプリケーション起動プロセスが必要となります。アプリケーション起動プロセスを使う場合は，MCF通信構成定義を作成しておいてください。

dc_mcf_execap関数で複数のMHPを起動させた場合にMCFイベントが通知されたときは，最初にdc_mcf_execap関数を呼び出したMHPの型を基に，MCFイベント処理用MHPの型が決定されます。SPPからdc_mcf_execap関数を呼び出した場合は，アプリケーション起動プロセスに対応するMCFイベントが通知されます。

MCFイベント処理用MHPとアプリケーションの型の関係を次の表に示します。

表3‒14　MCFイベント処理用MHPとアプリケーションの型の関係

MCFイベント処理用MHPを起動したMCFイベントのイベントコード

MCFイベント処理用MHPのアプリケーションの型

ERREVT1

要求元となった論理端末の端末タイプの型に応じて設定されます。

reply型論理端末の場合：ans

reply型以外の論理端末の場合：noans

ERREVT2

MCFイベントが通知される原因となった，MHPのアプリケーションの型をそのまま引き継ぎます。※

ERREVT3

ERREVT4

ERREVTA

非応答型（noans）が設定されます。

SERREVT

SCMPEVT

CERREVT

VERREVT

COPNEVT

VOPNEVT

CCLSEVT

VCLSEVT

注※

非トランザクション属性のMHPの場合は，異常終了したあとでもアプリケーションの型を引き継がないで，MCFイベント処理用MHPの指定に従います。

通信プロトコル対応製品と，通知されるMCFイベントの関係

通信プロトコル対応製品と，通知されるMCFイベントの関係を以降の表に示します。

表3‒15　通信プロトコル対応製品と通知されるMCFイベントの関係1

MCFイベント

通信プロトコル対応製品

TP1/NET/OSAS−NIF

TP1/NET/OSI-TP

TP1/NET/SLU-TypeP2

TP1/NET/TCP/IP

ERREVT1

○

○

○

○

ERREVT2

○

○

○

○

ERREVT3

○

○

○

○

ERREVT4

×

○

○

○

ERREVTA

○

○

○

○

SERREVT

×

×

×

×

SCMPEVT

×

×

×

○

CERREVT

○

○

○

○

COPNEVT

○

○

○

○

CCLSEVT

○

○

○

○

VERREVT

×

×

×

×

VOPNEVT

×

×

×

×

VCLSEVT

×

×

×

×

（凡例）

○：該当する通信プロトコル対応製品で通知されます。

×：該当する通信プロトコル対応製品では通知されません。

表3‒16　通信プロトコル対応製品と通知されるMCFイベントの関係2

MCFイベント

通信プロトコル対応製品

TP1/NET/User Agent

TP1/NET/UDP

TP1/NET/XMAP3

ERREVT1

○

○

○

ERREVT2

○

○

○

ERREVT3

○

○

○

ERREVT4

○

○

○

ERREVTA

○

○

○

SERREVT

×

×

○※

SCMPEVT

×

×

○※

CERREVT

○

○

×

COPNEVT

○

○

×

CCLSEVT

○

○

×

VERREVT

×

×

○

VOPNEVT

×

×

○

VCLSEVT

×

×

○

（凡例）

○：該当する通信プロトコル対応製品で通知されます。

×：該当する通信プロトコル対応製品では通知されません。

注※

SERREVT，SCMPEVTが通知されるのは，印刷機能を使用する場合だけです。

3.10.1　不正アプリケーション名検出通知イベント（ERREVT1）

ERREVT1は，受信したメッセージに設定されたアプリケーション名に，次に示す不良がある場合に通知されます。

アプリケーション名の形式が間違っている

アプリケーション名が，MCFアプリケーション定義にない

ERREVT1のMCFイベント処理用MHPでは，アプリケーション名が自ノードになかったことを伝える一方送信メッセージを送信するなどの対処をしてください。その際は，論理端末やUAPの型に従って，応答メッセージ，または一方送信メッセージをMCFイベント処理用MHPから送信してください。

ERREVT1の概要を次の図に示します。

図3‒24　ERREVT1の概要

メッセージを受信したMCFが，アプリケーション名に該当するMHPをスケジュールしようとしましたが，該当するMHPがありませんでした。

制御がMCFに戻り，ERREVT1が通知されて，ERREVT1のMCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPから，メッセージに該当するMHPがないことを伝える一方送信メッセージを送信します。

3.10.2　メッセージ廃棄通知イベント（ERREVT2）

ERREVT2は，次に示すことが原因で，受信したメッセージを廃棄した場合に通知されます。また，アプリケーション属性定義mcfaalcapの-nオプションにerrevt=yes（通信イベント障害時にエラーイベント通知する）を指定している通信イベントが，次に示す原因で障害が発生した場合にも，ERREVT2が通知されます。

入力キューに障害が発生した

入力メッセージ最大格納数を超過した

動的共用メモリが不足した

キューファイルが満杯になった

サービス，サービスグループ，またはアプリケーションが閉塞している

スケジュール閉塞されているサービスグループの入力キューに未処理受信メッセージが残った状態で，OpenTP1を正常終了または計画停止Aで終了した

サービスグループ，またはアプリケーションがセキュア状態である

MHPで呼び出すdc_mcf_receive関数にセグメントを渡す前に，MHPが異常終了した

アプリケーション名に相当する，MHPのサービスがない

ユーザサーバ未起動などによって，MHPの起動に失敗した

DBMSの障害などによって，トランザクションの開始に失敗した

ERREVT2のMCFイベント処理用MHPでは，ERREVT2の内容を参照して，自ノードで処理できなかったことを伝えるメッセージを送信するなどの対処をしてください。その際は，論理端末やUAPの型に従って，応答メッセージ，または一方送信メッセージをMCFイベント処理用MHPから送信してください。

ERREVT2の概要を次の図に示します。

図3‒25　ERREVT2の概要

受信したメッセージが，何らかの理由で入力キューから廃棄されました。

制御がMCFに戻り，ERREVT2が通知されて，ERREVT2のMCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPからメッセージを送ってきた他システムに，メッセージの再送要求などを伝える一方送信メッセージを送信します。

3.10.3　UAP異常終了通知イベント（ERREVT3）

ERREVT3は，次に示す場合に通知されます。また，アプリケーション属性定義 mcfaalcapの-nオプションにerrevt=yes（通信イベント障害時にエラーイベント通知する）を指定している通信イベントが，次に示す原因で障害が発生した場合にも，ERREVT3が通知されます。

MHPが，dc_mcf_receive関数で先頭セグメントを受信したあとで異常終了した

アプリケーション終了時，障害が発生した

ERREVT3は，MHPで呼び出したdc_mcf_rollback関数のフラグにDCMCFNRTNを設定してある場合にも通知されます。

ERREVT3のMCFイベント処理用MHPでは，ERREVT3の内容を参照して，自ノードのUAPが異常終了したことを伝えるメッセージのアプリケーション名をキーとして送信するなどの対処をしてください。その際は，論理端末やUAPの型に従って，応答メッセージ，または一方送信メッセージをMCFイベント処理用MHPから送信してください。

ERREVT3の概要を次の図に示します。

図3‒26　ERREVT3の概要

メッセージを受信したMHPの処理でエラーが起こると，ロールバックでリトライを設定していない場合，出力キューを経由して制御がMCFに戻ります。

エラーが発生したMHPから送られて来た情報を基に，ERREVT3が通知されます。

ERREVT3は入力キューを経由して，ERREVT3のMCFイベント処理用MHPをスケジュールします。MCFイベント処理用MHPは，メッセージを送ってきた他システムに，自システムのUAPでエラーが起こったことを伝えるメッセージを送信します。

3.10.4　タイマ起動メッセージ廃棄通知イベント（ERREVT4）

ERREVT4は，次に示すことが原因でメッセージを廃棄した場合に通知されます。

UAPからタイマ起動のアプリケーション起動（dc_mcf_execap関数）をして，MCFでタイマ監視中に，障害でメッセージを廃棄したとき

(1)　ERREVT4が通知されるまでの流れ

MHPからタイマ起動のdc_mcf_execap関数を呼び出すと，MCFでは出力キューからメッセージを取り出してタイマ監視をします。その時間待ちから入力キューに書き込むまでの間で，タイマ監視の失敗やスケジュールの失敗などの障害が起こると，ERREVT4が通知されます。その後，ERREVT4を処理するMCFイベント処理用MHPが起動されます。

ERREVT4の概要を次の図に示します。

図3‒27　ERREVT4の概要

タイマ起動のdc_mcf_execap関数を呼び出して，そのトランザクションがコミットすると，MCFでタイマ監視を始めます。

MCFでタイマ監視中に障害が起こると，ERREVT4が通知されます。

ERREVT4は入力キューを経由して，ERREVT4のMCFイベント処理用MHPをスケジュールします。

ERREVT4のMCFイベント処理用MHPでは，ERREVT4を解析して対処します。

3.10.5　未処理送信メッセージ廃棄通知イベント（ERREVTA）

ERREVTAは，次に示す場合に通知されます。

OpenTP1の正常終了コマンド（dcstopコマンド）を実行したあとに，出力キューに残っているメッセージを廃棄したとき

OpenTP1が稼働している間に，未処理送信メッセージが残っている出力キューをmcftdlqleコマンドまたはdc_mcf_tdlqle関数で削除したとき

タイマ起動のdc_mcf_execap関数を呼び出して，タイマ監視中にOpenTP1の正常終了コマンド（dcstopコマンド）を実行したとき

(1)　ERREVTAが通知されるまでの流れ

MHPが正常終了すると，出力キューに送信するメッセージが出力されます。閉塞解除されている論理端末において，メッセージが送信待ちしている状態で，OpenTP1を正常終了する場合，出力キューにある送信メッセージを送信し終わるまでMCFは終了を待ちます。このとき，送信する先のシステムの障害などで送信できない場合，時間切れ（タイムアウト）となり，送信するメッセージを廃棄します。このメッセージの廃棄を知らせるためにERREVTAが通知されます。タイムアウトになる時間は，タイマ定義（mcfttim -t）のmtimオペランドに指定した値で監視しています。

ただし，dc_mcf_execap関数によるタイマ起動要求メッセージや閉塞されている論理端末の出力キューに残っている未処理送信メッセージは，未処理送信メッセージ滞留時間の監視対象にはなりません。そのため，OpenTP1の正常終了コマンド（dcstopコマンド）を実行すると，メッセージはすぐに破棄され，ERREVTAが通知されます。

ERREVTAの概要を次の図に示します。

図3‒28　ERREVTAの概要

OpenTP1の正常終了コマンド（dcstopコマンド）を実行します。タイマ起動要求メッセージや閉塞されている論理端末の出力キューに未処理送信メッセージが残っていた場合は，このタイミングでメッセージが破棄され，MCFからERREVTAが通知されます。

MHPで正常に処理されたメッセージが出力キューに格納されます。

出力キューのメッセージの送信タイムアウトで，出力するメッセージが廃棄されました。

MCFからERREVTAが通知されます。

ERREVTAのMCFイベント処理用MHPがスケジュールされます。

ユーザファイルなどに退避します。

3.10.6　送信障害通知イベント（SERREVT）

SERREVTは，メッセージを正常に送信したUAPが処理を終了したあとで，MCFが相手システムへメッセージを送信する途中で通信プロトコルの障害が起こった場合に通知されます。このイベントを参照すると，非同期型のメッセージの送信（dc_mcf_send関数，dc_mcf_reply関数）を使った場合でも，通信プロトコルの障害が起こったことがわかります。

SERREVTのMCFイベント処理用MHPは，非応答型（noans型）です。

イベントを入力キューに書き込む前にOpenTP1を終了した場合は，SERREVTは通知されません。

SERREVTの概要を次の図に示します。

図3‒29　SERREVTの概要

dc_mcf_send関数，またはdc_mcf_reply関数に「イベントを通知する」ことを引数に設定して，メッセージを送信します。

UAPは正常終了します。UAPからの送信要求を受け取ったMCFは，メッセージを相手システムへ送信します。

通信プロトコルの障害が起こりました。

制御がMCFに戻り，SERREVTが通知されて，MCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPでは，SERREVTで通知された内容に合わせた処理をします。

3.10.7　送信完了通知イベント（SCMPEVT）

SCMPEVTは，メッセージを正常に送信できた場合にMCFから通知されます。このイベントによって，非同期型のメッセージの送信（dc_mcf_send関数，dc_mcf_reply関数）が正常に相手システムまで届いたことがわかります。

SCMPEVTのMCFイベント処理用MHPでは，送信完了と同期させる処理を開始できます。このときのMCFイベント処理用MHPは，非応答型（noans型）です。

イベントを入力キューに書き込む前にOpenTP1を終了した場合は，SCMPEVTは通知されません。

SCMPEVTの概要を次の図に示します。

図3‒30　SCMPEVTの概要

dc_mcf_send関数，またはdc_mcf_reply関数に「イベントを通知する」ことを引数に設定して，メッセージを送信します。

UAPからの送信要求を受け取ったMCFは，メッセージを相手システムへ送信します。

メッセージが相手システムへ正常に送信されました。

制御がMCFに戻り，SCMPEVTが通知されて，MCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPでは，SCMPEVTで通知された内容に合わせた処理をします。

3.10.8　障害通知イベント（CERREVT，VERREVT）

CERREVT（VERREVT）は，通信管理プログラムでコネクション障害，またはLE障害が起こったときに通知されます。ただし，MCF通信構成定義プロトコル固有定義にコネクション確立再試行を指定している場合は，CERREVT（VERREVT）は通知されません。

コネクション障害の通知方法は，プロトコル製品によって異なります。CERREVT（VERREVT）が通知される形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

CERREVT（VERREVT）の概要を次の図に示します。

図3‒31　CERREVT（VERREVT）の概要

相手システムとの通信中に，コネクションに障害が起こりました。

コネクション確立再試行を指定していない場合，および再試行回数の指定値を超えた場合，CERREVT（VERREVT）が通知されて，MCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPでは，CERREVT（VERREVT）で通知された内容に合わせた処理をします。

3.10.9　コネクション確立通知イベント（COPNEVT，VOPNEVT）

COPNEVT（VOPNEVT）は，MCFおよび通信管理プログラムが相手システムとのコネクションを確立したときに通知されます。COPNEVT（VOPNEVT）が通知されることで，コネクションが確立したことがMHPでわかります。

コネクション確立の通知方法は，プロトコル製品によって異なります。COPNEVT（VOPNEVT）が通知される形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

COPNEVT（VOPNEVT）の概要を次の図に示します。

図3‒32　COPNEVT（VOPNEVT）の概要

自OpenTP1システム，または相手システムからコネクションの確立を要求して，コネクションを確立します。この例では，自OpenTP1システムからコネクションの確立を要求します。プロトコル製品によっては，相手システムから応答が返らない場合もあります。

コネクションが確立されると，COPNEVT（VOPNEVT）が通知されて，MCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPでは，COPNEVT（VOPNEVT）で通知された内容に合わせた処理をします。

3.10.10　コネクション解放通知イベント（CCLSEVT，VCLSEVT）

CCLSEVT（VCLSEVT）は，MCFおよび通信管理プログラムが相手システムとのコネクションを解放したときに通知されます。CCLSEVT（VCLSEVT）が通知されることで，コネクションが解放されたことがMHPでわかります。

コネクション解放の通知方法は，プロトコル製品によって異なります。CCLSEVT（VCLSEVT）が通知される形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

CCLSEVT（VCLSEVT）の概要を次の図に示します。

図3‒33　CCLSEVT（VCLSEVT）の概要

自OpenTP1システム，または相手システムからコネクションの解放を要求して，コネクションを解放します。この例では，自OpenTP1システムからコネクションの解放を要求します。プロトコル製品によっては，相手システムから応答が返らない場合もあります。

コネクションが解放されると，CCLSEVT（VCLSEVT）が通知されて，MCFイベント処理用MHPがスケジュールされます。

MCFイベント処理用MHPでは，CCLSEVT（VCLSEVT）で通知された内容に合わせた処理をします。

3.10.11　MCFイベントのメッセージ形式

MCFイベントとして渡される論理メッセージは，MCFイベント情報と，処理できなかったメッセージから構成されます。処理できなかったメッセージは，通知されたMCFイベントによって異なります。

ERREVT1の場合

アプリケーションを特定できなかったメッセージ

ERREVT2の場合

アプリケーションの閉塞などで，目的のアプリケーションに渡せなかったメッセージ

ERREVT3の場合

異常終了したMHP（アプリケーション）で受信したメッセージ

ERREVT4の場合

タイマ起動のアプリケーションプログラムの起動で，開始するMHPに渡そうとしたメッセージ

ERREVTAの場合

出力キューで滞留していたメッセージ

次に示すMCFイベントの場合は，MCFイベント情報だけが渡されます。処理できなかったメッセージに該当するものはありません。

SERREVT

SCMPEVT

CERREVT（VERREVT）

COPNEVT（VOPNEVT）

CCLSEVT（VCLSEVT）

(1)　MCFイベントのメッセージ構造

MCFイベントをMCFイベント処理用MHPで受信する場合は，通常のメッセージを受信する関数（dc_mcf_receive関数）を使います。

MCFイベントは，複数セグメントの論理メッセージとして，MCFイベント処理用MHPに渡されます。先頭セグメントにはMCFイベント情報が，2番目以降のセグメントには処理できなかったメッセージのセグメントが設定されています。このとき，元の先頭セグメントは2番目のセグメントになり，以降一つずつずれてMCFイベントのセグメントとなります。

また，通信イベント障害時のエラーイベント通知機能（アプリケーション属性定義mcfaalcapの-nオプションにerrevt=yesを指定）によって起動されたMCFイベント処理用MHPにERREVT2またはERREVT3が渡されます。先頭セグメントにはMCFイベント情報が，2番目のセグメントに障害となった通信イベントのMCFイベント情報が設定されています。

MCFイベントとして渡される論理メッセージのセグメント形式を次の図に示します。

図3‒34　MCFイベントとして渡される論理メッセージのセグメント

(2)　通知されるデータ形式

MCFイベント情報は，MCFイベント処理用MHPをコーディングした高級言語（C言語，またはCOBOL言語）に合わせて通知されます。

C言語のMHPでは，MCFイベント情報を構造体で受け取れます。この構造体はヘッダファイル<dcmcf.h>で定義されています。MCFイベント情報を処理するMHPでは，＃includeで<dcmcf.h>をインクルードしてください。また，通信イベントによっては，通信プロトコル製品別のヘッダファイルに，構造体を定義している場合もあります。

COBOL言語のMHPでは，MCFイベント情報をセグメントの並びで受け取れます。このセグメントのバイト位置で必要な情報を取り出します。

MCFイベント情報のデータ形式は，通信プロトコル対応製品（TP1/NET/××××）によって異なります。次に示すMCFイベント情報のデータ形式については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

ERREVT1

ERREVT2

ERREVT3

ERREVTA

SERREVT

SCMPEVT

CERREVT（VERREVT）

COPNEVT（VOPNEVT）

CCLSEVT（VCLSEVT）

ERREVT4のMCFイベント情報のデータ形式については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

3.11　アプリケーションプログラムが使うMCFのプロセス

UAPが使うMCFのプロセスについて説明します。UAPがメッセージで通信するときには，次に示すMCFサービスのプロセスを使います。

MCF通信プロセス

自OpenTP1システムが，相手システムと通信するときに使うシステムプロセスです。

アプリケーション起動プロセス

OpenTP1システム内部でメッセージをやり取りするときに使うシステムプロセスです。

MCFのプロセスを上記のように分ける理由を，次に示します。

外部との通信と内部での通信でシステムプロセスを分けることで，MCFの通信に使うプロセスの負担を分散できます。

通信プロトコルの障害が原因でMCF通信プロセスが使えない場合でも，内部処理のプロセスに影響するのを防げます。

UAPで使うMCFのプロセスの概要を次の図に示します。

図3‒35　UAPで使うMCFのプロセスの概要

3.11.1　MCFのプロセスの種類

MCFのプロセス（MCF通信プロセス，アプリケーション起動プロセス）について説明します。

(1)　MCF通信プロセス

MCF通信プロセスは，自OpenTP1システムと相手システムが通信するときに使うプロセスです。UAPが次に示す関数で相手システムと通信するときに，MCF通信プロセスを使います。

メッセージの受信（dc_mcf_receive関数）

メッセージの送信（dc_mcf_send関数）

応答メッセージの送信（dc_mcf_reply関数）

同期型のメッセージの受信（dc_mcf_recvsync関数）

同期型のメッセージの送信（dc_mcf_sendsync関数）

同期型のメッセージの送受信（dc_mcf_sendrecv関数）

メッセージの再送（dc_mcf_resend関数）

MCF通信プロセスは，通信プロトコル対応製品ごとに作成します。一つのOpenTP1システムで異なる複数の通信プロトコルを使って通信する場合は，それぞれの通信プロトコル対応製品ごとに，MCF通信プロセスを定義します。

(2)　アプリケーション起動プロセス

アプリケーション起動プロセスは，自OpenTP1システム内部のMHPにメッセージを渡すときに使います。

アプリケーション起動プロセスを使うのは，次に示す機能を実行した場合です。

アプリケーションプログラムの起動（dc_mcf_execap関数）

MHPのロールバック（dc_mcf_rollback関数）でリトライ指定をした場合

通知されるMCFイベントのうち，エラーイベント（ERREVT×）を受信して業務で使う場合

MHPをmcfuevtコマンドで開始する場合

異常終了したMHPを再スケジュールする場合（アプリケーション属性定義（mcfaalcap）またはUAP共通定義（mcfmuap）のreschedulecntオペランドの指定値が1以上）

アプリケーション起動プロセスは，ほかのシステムとの通信では使いません（通信プロトコルに依存しません）。通常，アプリケーション起動プロセスはノードに一つ定義します。

3.11.2　MCFのプロセスを使うためのファイル

MCFサービスを使うためには，次に示すファイルを準備する必要があります。

定義オブジェクトファイル

MCFの実行形式プログラム

システムサービス情報定義ファイル

MCF通信プロセスの場合，通信プロトコル対応製品によって，定義する内容や生成するコマンドの文法が異なります。MCF通信プロセスに関する定義方法や定義コマンドユティリティについては，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編の説明を参照してください。

アプリケーション起動プロセスの場合は，通信プロトコルに依存しないで作成できます。アプリケーション起動プロセスに関する定義方法や定義コマンドユティリティについては，マニュアル「OpenTP1 システム定義」および「OpenTP1 運用と操作」を参照してください。

MCFサービスに必要なファイルのディレクトリ構成を，次の図に示します。

図3‒36　MCFサービスに必要なファイルのディレクトリ構成

4　ユーザデータを使う場合の機能

OpenTP1のファイルサービス（TP1/FS/Direct Access，TP1/FS/Table Access）を使う場合の機能，ISTサービス（TP1/Shared Table Access），ISAMファイルを使う場合の機能，他社のデータベースを使う場合の注意，および任意のファイルなどの資源を排他制御する場合の機能について説明します。

この章では，各機能をC言語の関数名で説明します。C言語の関数名に該当するCOBOL言語のAPIは，関数を最初に説明する個所に【 】で囲んで表記します。それ以降は，C言語の関数名に統一して説明します。

COBOL言語のAPIがない関数の場合は，【 】の表記はしません。

4.1　DAMファイルサービス（TP1/FS/Direct Access）

OpenTP1専用のユーザファイルとして使える，DAMファイルについて説明します。DAMファイルを使う場合は，システムにTP1/FS/Direct Accessが組み込まれていることが前提となります。また，OpenTP1の基本機能が TP1/Server Baseの場合だけ使えます。TP1/LiNKでは，DAMファイルサービスは使えません。

4.1.1　DAMファイルの構成

DAMファイルを構成する一つ一つのデータをブロックといいます。DAMファイルの1ブロックの大きさは，セクタ長×n−8（nは正の整数）バイトで指定します。

セクタ長は次のとおりです。

キャラクタ型スペシャルファイルの場合：filmkfsコマンドの-sオプション指定値

通常ファイルの場合：512バイト

DAMファイルの構成を次の図に示します。

図4‒1　DAMファイルの構成

4.1.2　物理ファイルと論理ファイル

UAPから呼び出す関数に指定する，DAMファイルの名称について説明します。

(1)　物理ファイル

DAMファイルを作成する場合は，DAMファイルとして使う領域をdamloadコマンドまたはオフラインの業務をするUAPで割り当てます。割り当てるときに使用する名称は，OpenTP1ファイルシステムとして割り当てたキャラクタ型スペシャルファイルのパス名です。このパス名で示すファイルを物理ファイル，ファイル名を物理ファイル名といいます。物理ファイル名は，割り当てたDAMファイルに初期データを作成したり，オフライン環境で更新したりする場合に使います。

(2)　論理ファイル

オンライン中にSUP，SPP，およびMHPからDAMファイルを使うときは，システム定義で名称を付けた，論理的なファイルに対してアクセスします。このファイルを論理ファイル，ファイル名を論理ファイル名といいます。論理ファイル名と物理ファイル名は，1対1に対応しています。物理ファイル名と論理ファイル名の対応は，DAMサービス定義で指定します。

(3)　UAPからアクセスする場合の注意

論理ファイルと物理ファイルはノードごとに定義するので，DAMファイルはノードごとに独立して管理されています。そのため，UAPからほかのノードにあるDAMファイルへはアクセスできません。DAMファイルを使う場合は，ノード（マシン）にあるUAPの処理から，ノード内で定義したファイル名でアクセスしてください。

4.1.3　DAMファイルへのアクセスの概要

DAMファイルにアクセスする方法について説明します。DAMファイルには，次の2種類があります。

回復対象のDAMファイル

UAPのトランザクション処理と同期してブロックを入出力します。

回復対象外のDAMファイル

トランザクション処理とは関係なくブロックを入出力します。

以降，回復対象のDAMファイル固有の機能については「回復対象のDAMファイルの場合」という断りを入れて説明します。回復対象外のDAMファイルについては，「4.1.8　回復対象外のDAMファイルへのアクセス」を参照してください。

(1)　DAMファイルへのアクセス手順の概要

UAPからDAMファイルを使う場合は，次の手順でアクセスします。

ファイルをオープンします。

次に示すうち，どれか一つの処理をします。

データの入力（参照），データの入力と更新，データの出力

ファイルをクローズします。

(2)　DAMファイルをオープンする場合の注意

DAMファイルをオープンする関数は，DAMファイルを使うUAPごとに呼び出します。同じグローバルトランザクションに属していても，DAMファイルのオープンはUAPごとに呼び出してください。

回復対象のDAMファイルの場合

論理ファイルのオープンは，トランザクションの範囲内でも範囲外でもできます。ただし，次に示すときは，論理ファイルにはブロック排他だけ指定できます。

トランザクションを開始する前に論理ファイルをオープンするとき

グローバルトランザクション単位で排他制御する指定をしたとき

(3)　DAMファイルからブロックを入力する場合の注意

DAMファイルのブロックは，参照目的の入力のときにかぎり，排他を指定しないで入力できます。ただし，排他を指定しないでブロックを入力した場合，入力処理中にほかのUAPから該当するブロックが更新されるため，最新のブロックの内容を入力できないことがあります。

(4)　トランザクションの範囲外からのDAMファイルへのアクセス（回復対象のDAMファイルの場合）

トランザクションの範囲外（トランザクションを開始する前，および同期点取得後）の処理からは，ブロックの入力だけできます。その場合は，参照目的のアクセスだけで，排他を指定できません。

(5)　DAMファイルへアクセスするトランザクションの範囲（回復対象のDAMファイルの場合）

DAMファイルへアクセスするときは，トランザクションブランチ単位で排他制御します。また，グローバルトランザクション単位でも排他制御できます。DAMファイルの排他については，「4.1.7　DAMファイルの排他制御」を参照してください。

(6)　2GBの容量を超えるDAMファイルをアクセスする場合の注意

DAMの入出力関数（dc_dam_get，dc_dam_put，dc_dam_read，dc_dam_rewrite，dc_dam_write，CBLDCDMB('GET')，CBLDCDMB('PUT')，CBLDCDAM('READ')，CBLDCDAM('REWT')，CBLDCDAM('WRIT')）で2GBを超えるDAMファイルデータを一度に入出力できません。2GBを超えるDAMファイルデータを一度に入出力しようとした場合は，DCDAMER_BUFER，または01604でエラーリターンします。

4.1.4　オンライン中のDAMファイルのアクセス（SUP，SPP，MHPからの操作）

オンライン中に，UAPからDAMファイルにアクセス（ファイルの参照や更新）するときは，トランザクションの中での処理が前提です。トランザクションを開始する前にDAMファイルをオープンした場合は，オープン以降に開始したすべてのトランザクションを終了させてからDAMファイルをクローズしてください。

(1)　DAMファイルにアクセスするときの名称

DAMファイルは，論理ファイル名を指定したdc_dam_open関数【CBLDCDAM('OPEN')】でオープンします。DAMファイルをオープンしたときに，そのファイルを識別する名称としてファイル記述子がリターンされます。オープン以降の処理（ファイルの入力，更新，出力）では，このファイル記述子を関数に設定してアクセスします。DAMファイルのクローズでもファイル記述子を設定したdc_dam_close関数【CBLDCDAM('CLOS')】でクローズします。ファイル記述子は，オープン以降の処理でもUAP内で保持しておいてください。

ファイル記述子が有効になる範囲を次に示します。

トランザクションの範囲内でファイルをオープンした場合

ファイル記述子は，次に示すことが起こるまで有効です。

論理ファイルのクローズ

トランザクションの同期点取得

UAPのプロセスの終了

トランザクションの範囲の外でファイルをオープンした場合

ファイル記述子は，次に示すことが起こるまで有効です。

論理ファイルのクローズ

UAPのプロセスの終了

処理の途中でDAMファイルを論理閉塞，閉塞を解除，およびファイルの状態を参照するときは，論理ファイル名を使います。

(2)　複数ブロックの一括入出力

複数の連続するブロックを，一括して入出力できます。DAMファイルを入出力するときに，アクセスするブロックの範囲を構造体として関数に設定します。ブロックの範囲は，相対ブロック番号で設定します。この構造体は複数個指定できます。

(3)　ブロックの参照／更新手順

DAMファイルのブロックを参照するときは，dc_dam_read関数【CBLDCDAM('READ')】でブロックを入力します。そのとき，ほかのトランザクションからの参照または更新を許すかどうかを設定できます。

DAMファイルのブロックの更新は，dc_dam_read関数でブロックを入力したあとで，そのブロックを更新するためにdc_dam_rewrite関数【CBLDCDAM('REWT')】を呼び出します。

DAMファイルからブロックを入力しないで，ブロックに上書きする出力をする場合は，dc_dam_write関数【CBLDCDAM('WRIT')】を呼び出します。

(4)　DAMファイルの論理閉塞と解除

DAMファイルのブロックを処理中に論理的な矛盾を発見した場合，そのDAMファイルに対してほかのUAPがアクセスできないように，UAPからdc_dam_hold関数【CBLDCDAM('HOLD')】を呼び出して閉塞できます。また，UAPからdc_dam_release関数【CBLDCDAM('RLES')】を呼び出して閉塞を解除できます。

オンライン中のDAMファイルのアクセス手順を次の図に示します。

図4‒2　オンライン時のDAMファイルのアクセス

(5)　トランザクション処理からのDAMファイルブロックへのアクセス（回復対象のDAMファイルの場合）

トランザクションの処理からDAMファイルにアクセスしてエラーが起こったときは，UAPからabort()を呼び出してトランザクションのプロセスを異常終了させてください。

以前にアクセスした関数によっては，同じトランザクション内からでも，一つのブロックに対するアクセスがエラーリターンすることがあります。エラーリターンするかどうかは，一つのトランザクション内から関数を呼び出したときと，異なるトランザクションから関数を呼び出したときで異なります。以前に呼び出した関数とDAMファイルのブロックにアクセスできる関数を表4-1と表4-2に示します。

表4‒1　一つのトランザクション内で，同じブロックにアクセスできる関数（回復対象のDAMファイルの場合）

前回呼び出した関数

今回呼び出した関数

結果またはエラーリターンする値

トランザクション内で，まだDAMファイルにアクセスする関数を呼び出していない

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力　排他を指定）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（更新目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

○

dc_dam_rewrite（更新の取り消し）

○

dc_dam_write（出力）

DCDAMER_SEQER（01605）

dc_dam_rewrite

（更新）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_rewrite

（更新の取り消し）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_write

（出力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

（凡例）

○：エラーになりません。

表4‒2　異なるトランザクションで，同じブロックにアクセスできる関数（回復対象のDAMファイルの場合）

前回呼び出した関数

今回呼び出した関数

結果またはエラーリターンする値

トランザクション内で，まだDAMファイルにアクセスする関数を呼び出していない

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力　排他を指定）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

DCDAMER_EXCER（01602）※

dc_dam_read

（更新目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

DCDAMER_EXCER（01602）※

dc_dam_read（更新目的の入力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite

（更新）

dc_dam_read（参照目的の入力）

○

dc_dam_read

（参照目的の入力　排他を指定）

DCDAMER_EXCER（01602）※

dc_dam_read（更新目的の入力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite

（更新の取り消し）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_write

（出力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

DCDAMER_EXCER（01602）※

dc_dam_read（更新目的の入力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

DCDAMER_EXCER（01602）※

（凡例）

○：エラーになりません。

注※

flagsにDCDAM_WAITを設定した場合は，排他解除待ちになります。

(6)　DAMサービスの関数がDCDAMER_PROTOでエラーリターンする原因

DAMサービスの関数がDCDAMER_PROTO（COBOL言語の場合は01600）でエラーリターンする原因を次に示します。原因は呼び出した関数によって異なります。

dc_rpc_open関数（COBOL言語の場合はCBLDCRPC('OPEN ')）を呼び出していません。

回復対象のDAMファイルの場合，ユーザサービス定義のatomic_updateの指定が'N'になっています。

次に示すように，UAPを正しくリンケージしていません。

DAMサービスのAPIでTAMファイルにアクセスする場合に使うライブラリ（-ltdam）を，不当にリンケージしています。

トランザクション制御用オブジェクトファイルのリソースマネジャ登録が間違っています。

ユーザサービス定義のatomic_updateオペランドの指定が'N'の場合に，dc_dam_start関数（COBOL言語の場合はCBLDCDAM('STRT')）を呼び出していません（回復対象外のDAMファイルの場合）。

(7)　DAMファイルの状態の参照

使っているDAMファイルの状態を，オンライン中に参照できます。DAMファイルの状態を参照するときは，dc_dam_status関数【CBLDCDAM('STAT')】を呼び出します。

dc_dam_status関数で参照できる情報を次に示します。

論理ファイルのブロック数

論理ファイルのブロック長

論理ファイルに対応した物理ファイル名

論理ファイルの現在の状態（閉塞されているかどうか）

DAMサービス定義で指定した論理ファイルの属性

DAMサービス定義で指定した論理ファイルのセキュリティ属性

(a)　dc_dam_status関数を使う場合の注意

dc_dam_status関数を呼び出すと，DAMサービスは情報を取得するための排他制御をします。そのため，dc_dam_status関数を頻繁に使うと，排他の解除待ちが起こってスループットが低下することがあります。オンライン中にDAMファイルの状態を参照するのは，必要最小限にしてください。

4.1.5　オフライン中のDAMファイルのアクセス（オフラインの業務をするUAPからの操作）

バッチ環境ではDAMファイルの内容を出力できます。オフラインでオープンした物理ファイルは，処理を終了したら必ずクローズさせてください。なお，オフラインで使用する関数は，オンライン（SUP，SPP，MHP）では使用できません。使用した場合の動作は保証できません。

(1)　DAMファイルにアクセスするときの名称

物理ファイルを，割り当てたときに設定した物理ファイル名を設定したdc_dam_iopen関数【CBLDCDMB('OPEN')】でオープンします。物理ファイルをオープンしたときにファイル記述子がリターンされます。ファイル記述子は，オープンしてからクローズするまでの処理で使うので，UAP内で保持しておいてください。

オープン以降の処理（ブロックの入力，出力）は，このファイル記述子を関数に設定してアクセスします。物理ファイルのクローズもファイル記述子を設定したdc_dam_iclose関数【CBLDCDMB('CLOS')】でクローズします。

(2)　ブロックの入力と出力

dc_dam_iopen関数でオープンした物理ファイルのブロックを入出力するときは，次に示す2種類の方法があります。

ファイルの先頭から順番に入出力する場合

ブロックを入力する場合はdc_dam_get関数【CBLDCDMB('GET ')】，ブロックを出力する場合はdc_dam_put関数【CBLDCDMB('PUT ')】を呼び出します。このとき，物理ファイルをオープンしたあとに，UAPの処理で入力と出力を混在できません。いったん物理ファイルをクローズしてからにしてください。

任意のブロックを入出力する場合

任意のブロックを入出力する場合は，dc_dam_iopen関数にOVERWRITEを設定して物理ファイルをオープンしてください。そのほかの関数を呼び出して物理ファイルをオープンした場合は，任意のブロックを入出力できません。

任意のブロックを入出力には，2種類の方法があります。この2種類の方法は混在できません。どちらかの方法でブロックを入出力してください。

入出力するブロックの相対ブロック番号を検索します。検索するときは，dc_dam_bseek関数【CBLDCDMB('BSEK')】を呼び出します。

検索し終わってからブロックを入力する場合はdc_dam_get関数，ブロックを出力する場合はdc_dam_put関数を使います。このとき，dc_dam_iopen関数からdc_dam_iclose関数の処理の間では，入力と出力を混在できます。

入出力するブロックの相対ブロック番号を指定して，次のどちらかの関数を呼び出します。入力と出力は混在できます。

入力する場合：dc_dam_dget関数【CBLDCDMB('DGET')】

出力する場合：dc_dam_dput関数【CBLDCDMB('DPUT')】

複数ブロックを一括入出力する指定は，ファイルの先頭から順番に入出力する場合だけ有効です。

(3)　複数ブロックの一括入出力

物理ファイルを割り当てるときとオープンするときに，入出力する単位としてブロック数を指定できます。

(4)　ブロックの初期作成と再作成

入力したブロックを物理ファイルに出力するときに，出力するブロック以降にある残りの領域を，ヌル文字で埋めるかどうかを設定できます。出力するブロック以降の残りの領域をヌル文字で埋めるときはINITIALIZEを設定します。ヌル文字でクリアしないときは，OVERWRITEを設定します。OVERWRITEを設定した場合には，任意のブロックの入出力ができます。このとき，出力したブロック以降の領域は更新されないでそのまま残ります。

残りのブロックをヌル文字で埋めるかどうかは，dc_dam_iopen関数の引数で指定します。この指定は，dc_dam_put関数でブロックを出力してdc_dam_iclose関数でクローズしたときに有効です。dc_dam_iclose関数を呼び出さないでUAPを終了した場合は，残りのブロックをヌル文字で埋めません。ヌル文字で埋める場合は，必ずdc_dam_iclose関数を呼び出してください。

オフライン中のDAMファイルのアクセス手順を次の図に示します。

図4‒3　オフライン時のDAMファイルのアクセス手順

4.1.6　物理ファイルの作成（オフラインの業務をするUAPからの操作）

物理ファイルはオフラインで作成します。物理ファイルは，まずOpenTP1ファイルシステムにdc_dam_create関数【CBLDCDMB('CRAT')】で割り当てます。割り当てるときに設定する内容を次に示します。

割り当てる物理ファイル名

一つのブロックのブロック長と，ブロック数

入出力の単位になる，一括処理ブロック数

ファイル所有者，所有者グループ，ほかのUAPからのアクセス権

物理ファイルを割り当てたときに，ファイル記述子がリターンされます。

ファイル記述子は，オープン以降の処理で使います。dc_dam_create関数で返されたファイル記述子を使える関数を次に示します。

dc_dam_put関数（ブロックの出力）

dc_dam_iclose関数（ファイルのクローズ）

次に示す関数では，dc_dam_create関数で返されたファイル記述子を使えません。関数はエラーリターンします。

dc_dam_get関数（ブロックの入力）

dc_dam_dget関数，dc_dam_dput関数（ブロックの直接入出力）

dc_dam_bseek関数（ブロックの検索）

OpenTP1ファイルシステムに，最初に物理ファイルとしてDAMファイルを作成する手順を次の図に示します。

図4‒4　DAMファイルの作成手順

4.1.7　DAMファイルの排他制御

DAMファイルの更新中に，ほかのUAPからの更新処理が割り込むと，一つの論理ファイルに二つの処理が同時に反映されて，ファイルの内容に矛盾が生じてしまいます。このようなことを防ぐため，DAMファイルにアクセスする関数で排他制御をします。排他を制御することで，複数のUAPからアクセスされるDAMファイルでも，データの整合性を保証できます。

DAMファイルへアクセスするトランザクションの範囲（回復対象のDAMファイルの場合）

DAMファイルへアクセスするときは，トランザクションブランチ単位の排他制御となります。そのため一つのグローバルトランザクションに属する複数のトランザクションブランチから同じブロックまたは同じファイルにアクセスしても，排他エラーになる場合があります。このようなエラーを避けるため，グローバルトランザクション単位で排他制御することもできます。グローバルトランザクション単位で排他制御する場合は，該当するDAMファイルのDAMサービス定義にグローバルトランザクション単位でアクセスすることを指定します。

グローバルトランザクション単位で排他制御する場合，トランザクションブランチごとにDAMファイルにアクセスしても，並列にアクセスできないで順次アクセスになります。そのため，トランザクションの性能が下がる場合があります。トランザクションブランチごとのDAMファイルへのアクセスを並列に処理させる場合は，グローバルトランザクション単位での排他制御は指定しないでください。

(1)　排他制御モード

DAMファイルアクセス時の排他の条件を排他制御モードといいます。排他制御モードには，次の2種類があります。

参照目的の排他（共用モード　PR　Protected Retrieve）

UAPは排他指定したファイルの参照だけできます。ほかのトランザクションには，参照だけを許可します。

更新目的の排他（排他モード　EX　EXclusive）

UAPは排他指定したファイルの参照，更新ができます。ほかのトランザクションには，参照，更新を禁止します。

(2)　排他の指定単位（回復対象のDAMファイルの場合）

オンライン中のDAMファイルへのアクセスに対する排他の指定単位には，次の2種類があります。

(a)　ブロック排他

ブロック単位に排他制御をします。ブロックを参照するときは共用モードの排他が掛かり，ブロック更新，またはブロック出力時には排他モードの排他が掛かります。参照目的での排他指定は，オプションの指定で排他をしない（ほかのUAPに参照／更新を許す）こともできます。確保された排他の指定は，DAMファイルへの処理を指定したトランザクション処理が正常終了したときに解除されます。

(b)　ファイル排他

論理ファイル単位で排他制御します。論理ファイル全体に対して，ファイルのオープンからトランザクション処理の正常終了まで排他が掛かります。

ファイル排他を指定できるのは次の場合です。

トランザクションブランチ単位で排他制御する指定で，トランザクションの範囲内で論理ファイルをオープンした場合

次に示す場合は，ファイル排他を指定できません。ブロック排他で排他制御をしてください。

トランザクションの範囲外で論理ファイルをオープンした場合

グローバルトランザクション単位で排他制御する指定をした場合

(3)　資源の排他解除待ちの設定（回復対象のDAMファイルの場合）

dc_dam_open関数

入出力しようとしたブロックが，すでにほかのトランザクションから排他をかけられていた場合（排他エラー），アクセスした関数をエラーリターンするか排他が解除されるのを待つかを，DAMファイルのオープン時にdc_dam_open関数の引数で設定できます。

ファイル排他でDAMファイルをオープンする場合，排他待ち種別は設定できません。

dc_dam_open関数でファイルをオープンしようとしたときに排他エラーが起こった場合は，無条件にエラーリターンします。

dc_dam_read関数とdc_dam_write関数

排他エラーが起こった場合，dc_dam_read関数とdc_dam_write関数の排他待ち種別（エラーリターンするか，排他が解除されるのを待つか）を設定できます。この設定を省略した場合は，dc_dam_open関数に設定した値に従います。

排他が解除されるのを待つと設定した場合に，デッドロックやタイムアウトが起こったときは，排他の解除を待っている関数がエラーリターンしたあと，デッドロック情報が出力されます。デッドロックやタイムアウトで関数がエラーリターンした場合は，トランザクションの同期点を取得して，確保した資源をすべて解放してください。

(4)　オンライン時とオフライン時の排他

オンラインで使っているDAMファイルは，オフラインでアクセスできません。オンラインで使っているDAMファイルにオフラインのアクセスをする場合は，damhold，damrmコマンドで，いったんオンラインから削除してからオフラインでアクセスしてください。その後，damaddコマンドでオンラインに復帰させてください。

オフライン時でも，異なるUAPが同じDAMファイルに同時にはアクセスできません。DAMファイルをオープンしたUAPのプロセスが，クローズするまでそのDAMファイルを占有します。

4.1.8　回復対象外のDAMファイルへのアクセス

トランザクションによる整合性の管理や障害時の回復を保証しないDAMファイルを作成できます。このようなDAMファイルを回復対象外のDAMファイルといいます。回復対象外のDAMファイルのブロックは，トランザクションの処理でなくても，dc_dam_write関数，dc_dam_rewrite関数で更新できます。

(1)　回復対象外のDAMファイルの定義

回復対象外にするDAMファイルを定義するときには，DAMサービス定義のdamfile定義コマンドに-nオプションを付けて指定します。

(2)　回復対象外のDAMファイルへのアクセス

ファイルへアクセスをする前にdc_dam_start関数【CBLDCDAM('STRT')】を，アクセスを完了するときにはdc_dam_end関数【CBLDCDAM('END ')】を呼び出します。dc_dam_start関数を呼び出したときは，アクセス終了後，必ずdc_dam_end関数を呼び出してください。

回復対象外のDAMファイルへは，DAMサービスの関数を使ってアクセスします。回復対象のDAMファイルへアクセスする場合と同様に，アクセスできます。

ファイルをオープンしたときのファイル記述子は，次に示すことが起こるまで有効です。

論理ファイルのクローズ

回復対象外のDAMファイルの使用終了（dc_dam_end関数の呼び出し）

UAPのプロセスの終了

(3)　ファイルアクセスでエラーが起こった場合の処置

回復対象外のDAMファイルへのアクセスでエラーが起こった場合でも，ファイルデータの障害は回復できません。

回復対象外のDAMファイルへのアクセス手順を次の図に示します。

図4‒5　回復対象外のDAMファイルへのアクセス手順

(4)　回復対象外のDAMファイルへアクセスする関数の関係

以前にアクセスした関数によっては，同じUAPの処理からでも，一つのブロックに対するアクセスがエラーリターンすることがあります。エラーリターンするかどうかは，一つのUAPから呼び出したときと異なるUAPから呼び出したときで異なります。以前に呼び出した関数とDAMファイルのブロックにアクセスできる関数を表4-3と表4-4に示します。

表4‒3　一つのUAP内で，同じブロックにアクセスできる関数（回復対象外のDAMファイルの場合）

前回呼び出した関数

今回呼び出した関数

結果またはエラーリターンする値

dc_dam_start関数を呼び出したあと，まだDAMファイルにアクセスする関数を呼び出していない

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力　排他を指定）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（更新目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

○

dc_dam_rewrite（更新の取り消し）

○

dc_dam_write（出力）

○

dc_dam_rewrite

（更新）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_rewrite

（更新の取り消し）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_write

（出力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

（凡例）

○：エラーになりません。

表4‒4　異なるUAP内で，同じブロックにアクセスできる関数（回復対象外のDAMファイルの場合）

前回呼び出した関数

今回呼び出した関数

結果またはエラーリターンする値

dc_dam_start関数を呼び出したあと，まだDAMファイルにアクセスする関数を呼び出していない

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（参照目的の入力　排他を指定）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_read

（更新目的の入力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

DCDAMER_EXCER（01602）※

dc_dam_read（更新目的の入力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

DCDAMER_EXCER（01602）※

dc_dam_rewrite

（更新）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_rewrite

（更新の取り消し）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

dc_dam_write

（出力）

dc_dam_read（参照目的の入力）

○

dc_dam_read（参照目的の入力　排他を指定）

○

dc_dam_read（更新目的の入力）

○

dc_dam_rewrite（更新）

DCDAMER_SEQER（01605）

dc_dam_rewrite（更新の取り消し）

DCDAMER_SEQER（01605）

dc_dam_write（出力）

○

（凡例）

○：エラーになりません。

注※

flagsにDCDAM_WAITを設定した場合は，排他解除待ちになります。

(5)　回復対象外のDAMファイルの排他制御

回復対象のDAMファイルと同様に，回復対象外DAMファイルでも排他制御をします。ここでは，回復対象外のDAMファイルの排他制御について説明します。回復対象のDAMファイルと回復対象外のDAMファイルの比較については，「4.1.8(6)　回復対象のDAMファイルと回復対象外のDAMファイルとの比較」を参照してください。

(a)　回復対象外のDAMファイルの排他範囲

回復対象外のDAMファイルの場合，トランザクションの範囲内かどうかに関係なく，DAMファイルへアクセスできます。

(b)　排他制御モード

回復対象外のDAMファイルの排他制御モードは，回復対象のDAMファイルと同じです。排他制御モードについては，「4.1.7(1)　排他制御モード」を参照してください。

(c)　排他の指定単位

回復対象外のDAMファイルの排他の指定単位は，回復対象のDAMファイルと同じです。排他の指定単位については，「4.1.7(2)　排他の指定単位（回復対象のDAMファイルの場合）」を参照してください。

(d)　資源の排他解除待ちの設定

回復対象外のDAMファイルの資源の排他解除待ちの設定は，次に示す点を除いて，回復対象のDAMファイルと同じです。

dc_dam_open関数に設定する排他解除待ちの種別は，dc_dam_open関数自体の指定を含みます。回復対象のDAMファイルの場合は，dc_dam_open関数で排他エラーが起こると無条件にエラーリターンしましたが，回復対象外のDAMファイルでは，引数に設定した排他待ち種別に従って処理できます。

資源の排他待ちの設定については，「4.1.7(3)　資源の排他解除待ちの設定（回復対象のDAMファイルの場合）」を参照してください。

(6)　回復対象のDAMファイルと回復対象外のDAMファイルとの比較

回復対象のDAMファイルと回復対象外のDAMファイルとの比較について説明します。アクセスの違いを表4-5に，アクセス時に排他制御する範囲の違いを表4-6に示します。

表4‒5　回復対象のDAMファイルと回復対象外のDAMファイルとのアクセスの違い

DAMサービスの関数

関数を呼び出す条件

DAMファイルの種類とアクセスする位置

回復対象DAMファイル

回復対象外

DAMファイル

トランザクション範囲外

トランザクション範囲

dc_dam_open

ファイル排他，排他解除待ち

×

○

○

ファイル排他，即時リターン

×

○

○

ブロック排他，排他解除待ち

○

○

○

ブロック排他，即時リターン

○

○

○

dc_dam_close

トランザクションの範囲でファイルをオープン

○

○

○

トランザクションの範囲外でファイルをオープン

−

×

○

dc_dam_read

参照目的の入力，排他なし

○

○

○

参照目的の入力，排他を指定

×

○

○

更新目的の入力，排他を指定

×

○

○

dc_dam_rewrite

更新目的の出力

×

○

○

更新の取り消し

×

○

○

dc_dam_write

（条件なし）

×

○

○

（凡例）

○：該当する条件で，関数を呼び出せます。

×：該当する条件で，関数を呼び出すとエラーリターンします。

−：該当する条件では，関数を呼び出せません。

表4‒6　回復対象のDAMファイルと回復対象外のDAMファイルとのアクセス時に排他制御する範囲の違い

排他の指定単位※と呼び出す関数

排他制御モード

回復対象DAMファイルの場合

回復対象外DAMファイルの場合

ファイル

排他

dc_dam_open

EX

同期点処理の終了まで排他

dc_dam_closeまたはdc_dam_endの理が終了するまで排他

ブロック

排他

dc_dam_read

（参照）

PR

同期点処理の終了まで排他

dc_dam_readの処理が終了するまで排他

dc_dam_read

（更新）

EX

同期点処理の終了まで排他

dc_dam_rewrite（取り消し）の処理が終了するまで排他

dc_dam_rewrite（更新または取り消し）の処理が終了するまで排他

dc_dam_write

EX

同期点処理の終了まで排他

dc_dam_writeの処理が終了するまで排他

注※

ここで示す排他の指定単位は，dc_dam_open関数に設定した場合です。dc_dam_open関数にファイル排他を指定した場合，dc_dam_read関数，dc_dam_write関数に設定した排他の指定単位は無効です。

4.1.9　DAMサービスとTAMサービスとの互換

DAMサービスの関数で，TAMファイルのレコードにアクセスできます。詳細については，「4.2.9　TAMサービスとDAMサービスとの互換」を参照してください。

4.2　TAMファイルサービス（TP1/FS/Table Access）

OpenTP1専用のユーザファイルとして使える，TAMファイルについて説明します。TAMファイルを使うと，直接編成ファイルへ高速にアクセスできます。

TAMファイルを使う場合は，システムにTP1/FS/Table Accessが組み込まれていることが前提となります。また，OpenTP1の基本機能がTP1/Server Baseの場合だけ使えます。TP1/LiNKでは，TAMファイルサービスは使えません。

4.2.1　TAMファイルの構成

TAMファイルを構成する一つ一つのデータをレコードといいます。TAMファイルのキーとレコードは，メモリにロードされます。実際のファイルでなく，メモリへのキーアクセスによって，UAPからの高速アクセスを実現できます。このインデクス部とデータ部をTAMテーブルといいます。

TAMテーブルは，レコードに対応させるキーがあるインデクス部と，レコードがあるデータ部から構成されます。

(1)　TAMテーブルのインデクス種別

インデクス種別には，ハッシュ形式とツリー形式があります。ハッシュ形式とツリー形式では，キーとレコードの対応のさせ方が異なります。また，TAMテーブルにアクセスするときは，使うTAMテーブルのインデクス種別を確認してから，UAPを作成してください。異なるインデクス種別のTAMテーブルにアクセスすると，UAPのTAMアクセス関数はエラーリターンします。

(2)　TAMテーブルへのアクセス環境

TAMテーブルには，オンラインでだけアクセスできます。オフライン環境ではTAMテーブルにはアクセスできません。また，UAPからTAMテーブルにアクセスするときは，TAMサービス定義で指定したアクセス形態に従ってください。定義されていないアクセスをすると，UAPのTAMアクセス関数はエラーリターンします。

TAMファイルの構成を次の図に示します。

図4‒6　TAMファイルの構成

4.2.2　TAMテーブルへアクセスするときの条件

TAMテーブルへのアクセスは，アクセスするトランザクションブランチが存在するノード（マシン）にあるTAMファイルのテーブルにだけできます。ノードごとのTAMテーブルに対する処理は独立しているので，TAMテーブル名はノードごとで管理しています。グローバルトランザクション内でTAMテーブルにアクセスするときは，ノード内でのテーブル名でアクセスしてください。

(1)　UAPからTAMテーブルへのアクセスとトランザクションの関数

TAMテーブルのオープンとクローズは，トランザクション開始前でも開始後でもできます。ただし，TAMテーブルのオープンとクローズ以外の関数（テーブルの参照や更新）は，必ずトランザクションを開始したあとで使ってください。

トランザクションを開始する前にTAMテーブルをオープンした場合は，オープン以降に開始したすべてのトランザクションを終了させてから，TAMテーブルをクローズしてください。

(2)　TAMテーブルへのアクセスとRPCの形態

TAMテーブルへのアクセスでは，グローバルトランザクションのRPCの形態がすべて同期応答型RPCでなければなりません。非同期応答型RPC，非応答型RPCからTAMテーブルへアクセスした場合の動作は保証しません。

4.2.3　TAMテーブルへアクセスするときの名称

TAMテーブルは，TAMテーブル名でオープンします。TAMテーブルをオープンしたときに，そのテーブルを識別する名称としてテーブル記述子がリターンされます。オープン以降の処理（レコードの入力，更新，追加，削除など）は，このテーブル記述子を関数に設定してアクセスします。

4.2.4　TAMテーブルへのアクセス手順

(1)　TAMテーブルのオープン

C言語のUAPの場合，dc_tam_open関数でTAMテーブルをオープンします※。TAMテーブルをオープンするときは，UAPごとにdc_tam_open関数を呼び出してください。

トランザクションの範囲内でも範囲外でも，TAMテーブルはオープンできます。ただし，トランザクションを開始する前にTAMテーブルをオープンする場合は，そのテーブルに対する排他はできません。TAMテーブルの排他については，「4.2.6　TAMテーブルの排他制御」を参照してください。

TAMテーブルのクローズもテーブル記述子を設定してクローズします※。テーブル記述子は，オープン以降の処理でもUAP内で保持しておいてください。

注※

COBOL言語でUAPをコーディングする場合は，UAPからTAMテーブルのオープンとクローズはしません。TAMテーブルにアクセスした時点で，該当のTAMテーブルがオープンされて，トランザクションが完了した時点で，該当のTAMテーブルはクローズされます。

(2)　レコードの入力／更新／追加／削除手順

TAMテーブルのレコードを参照または更新目的で入力するときは，dc_tam_read関数【CBLDCTAM('FxxR')('FxxU')('VxxR')('VxxU')】を呼び出します。そのとき，別のグローバルトランザクションからの参照または更新を許すかどうかを設定できます。

TAMテーブルのレコードを更新するときは，dc_tam_read関数でレコードを入力したあとに，dc_tam_rewrite関数【CBLDCTAM('MFY ')('MFYS')('STR ')('WFY ')('WFYS')('YTR ')】を呼び出します（入力前提の更新）。

TAMテーブルからレコードを入力しないで，すでにあるレコードに上書きする更新，またはレコードを新規追加する場合は，dc_tam_write関数【CBLDCTAM('MFY ')('MFYS')('STR ')('WFY ')('WFYS')('YTR ')】を呼び出します。

TAMテーブルのレコードを削除する場合は，dc_tam_delete関数【CBLDCTAM('ERS ')('ERSR')('BRS ')('BRSR')】を呼び出します。削除するレコードは，任意のアドレスのバッファに退避できます。退避先のアドレスは，dc_tam_delete関数に設定します。

dc_tam_read関数，またはdc_tam_delete関数のバッファ域，およびdc_tam_rewrite関数，またはdc_tam_write関数のデータ域の先頭を，4バイト境界で設定した場合，設定しない場合に比べて，より高速なアクセスができます。

(3)　複数レコードの一括入出力

複数のキー値（レコード）を，一括して入出力できます。TAMテーブルを入出力するときに，アクセスするキー値を構造体として関数に設定します。この構造体は複数個指定できます。

(4)　インデクス種別によるレコードの入力

TAMテーブルからレコードを入力するときは，インデクス種別によって設定できる検索種別が異なります。

ハッシュ形式の場合

先頭検索とNEXT検索ができます。これらの検索を使用すると，全レコード検索ができます。最初にdc_tam_read関数（先頭レコード入力を設定）を呼び出して，先頭レコードを入力します。そのキー値以降のレコードは，dc_tam_read関数のNEXT検索で順に入力していきます。

全レコード検索は，TAMテーブルのレコードを全件削除などに使用できます。TAMテーブルのレコードを全件削除する方法を次に示します。

先頭検索で先頭レコードを取得する。

先頭レコードをキー値に指定してNEXT検索をして，次のレコードを取得する。

先頭レコードを削除する。

現在取得しているレコードをキー値に指定してNEXT検索をして，次のレコードを取得する。

4でキー値に指定したレコードを削除する。

次のレコードがなくなるまで4，5の手順を繰り返す。

次のレコードがなくなったら，最後のNEXT検索でキー値に指定したレコードを削除する。

この方法は，検索の開始位置としてキー値を指定するので，先頭から指定したキー値の前までの空のハッシュ域は検索しません。そのため，効率良く検索できます。

次の方法はCPUを多く消費するため，レスポンスが遅延する可能性があります。

先頭検索で先頭レコードを取得する。

先頭レコードを削除する。

レコードがなくなるまで1，2の手順を繰り返す。

先頭検索はハッシュ域を先頭から探す処理です。この方法の場合，直前までの処理でレコードを削除して空になったハッシュ域を含めて，毎回先頭からレコードを検索するため，効率が悪く，レスポンスが遅延する可能性があります。

ツリー形式の場合

設定したキー値に対して「＝」，「＜＝」，「＞＝」，「＜」，および「＞」の条件で検索できます。検索後，キー値に該当するレコードを入力します。ある範囲の複数のキー値のレコードを入力するときは，「＝」，「＜＝」，「＞＝」，「＜」および「＞」を設定すれば，その条件に該当するレコードを順に入力できます。

(5)　TAMテーブルのクローズ

TAMテーブルは，dc_tam_close関数でクローズします。

トランザクションの範囲内でTAMテーブルをオープンしたときは，トランザクション内でクローズしてください。クローズをしないでトランザクションを終了させたときは，OpenTP1でTAMテーブルをクローズします。

トランザクションの範囲外でTAMテーブルをオープンしたときは，トランザクションの外でクローズしてください。トランザクション内でdc_tam_close関数を呼び出すとエラーリターンします。

TAMテーブルのアクセス手順を次の図に示します。

図4‒7　TAMテーブルのアクセス手順

(6)　TAMテーブルの状態を取得

オンライン中にTAMテーブルの状態を知りたい場合は，dc_tam_get_inf関数【CBLDCTAM('GST ')】を使います。dc_tam_get_inf関数は，トランザクション処理からでもトランザクションでない処理からでも呼び出せます。dc_tam_get_inf関数では，TAMテーブルが次に示すどの状態かを返します。

オープン状態

クローズ状態

論理閉塞状態

障害閉塞状態

dc_tam_get_inf関数を呼び出したUAPがTAMテーブルをオープンしていなくても，ほかのUAPがTAMテーブルをオープンしていれば，dc_tam_get_inf関数はオープン状態を返します。

(7)　TAMテーブルの情報を取得

オンライン中にTAMテーブルの情報を知りたい場合は，dc_tam_status関数【CBLDCTAM('INFO')】を使います。dc_tam_status関数は，トランザクション処理からでもトランザクションでない処理からでも呼び出せます。dc_tam_status関数は，次に示すTAMテーブルの情報を返します。

TAMファイル名

TAMテーブルの状態

使用中のレコード数

最大レコード数

インデクス種別

アクセス形態

ローディング契機

TAMレコード長

キー長

キー開始位置

セキュリティ属性

4.2.5　トランザクションとTAMアクセスの関係

トランザクションブランチで，TAMアクセスのエラーが起こった場合は，UAPからabort()を呼び出して，そのグローバルトランザクションのプロセスを異常終了させてください。

同じグローバルトランザクション内でも，以前にアクセスした関数によっては，一つのレコードに対するアクセスがエラーリターンする場合があります。また，同じレコードへのアクセスでも，同じグローバルトランザクションに属するときと，異なるグローバルトランザクションからの場合では，結果が異なります。

同じレコードに対して関数を複数回呼び出したときの処理結果を表4-7と表4-8に示します。

表4‒7　同じレコードに対して関数を複数回呼び出したときの処理結果（一つのグローバルトランザクション）

前回呼び出した関数

今回呼び出した関数

結果またはエラーリターンする値

トランザクション内で，まだTAMテーブルにアクセスする関数を呼び出していない

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

DCTAMER_SEQENCE（01732）

dc_tam_rewrite（入力前提の更新）

DCTAMER_SEQENCE（01732）

dc_tam_write（更新）

○

dc_tam_write（追加）

○

dc_tam_delete（削除）

○

dc_tam_read

（参照目的の入力）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

DCTAMER_SEQENCE（01732）

dc_tam_rewrite（入力前提の更新）

DCTAMER_SEQENCE（01732）

dc_tam_write（更新）

○

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○

dc_tam_read

（参照目的の入力　排他を指定）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

○※1

dc_tam_rewrite（入力前提の更新）

DCTAMER_SEQENCE（01732）

dc_tam_write（更新）

○

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○

dc_tam_read

（更新目的の入力）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

○

dc_tam_rewrite（入力前提の更新）

○

dc_tam_write（更新）

○

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○

dc_tam_read_cancel

（入力の取り消し）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

DCTAMER_SEQENCE（01732）※2

dc_tam_rewrite（入力前提の更新）

DCTAMER_SEQENCE（01732）

dc_tam_write（更新）

○

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○

dc_tam_rewrite

（入力前提の更新）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

DCTAMER_EXREWRT（01734）

dc_tam_rewrite（入力前提の更新）

○

dc_tam_write（更新）

○

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○

dc_tam_write

（更新，または追加）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

DCTAMER_SEQENCE（01732）

dc_tam_rewrite（入力前提の更新）

DCTAMER_SEQENCE（01732）

dc_tam_write（更新）

○

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○

dc_tam_delete

（削除）

dc_tam_read（参照目的の入力）

DCTAMER_NOREC（01731）

dc_tam_read（参照目的の入力　排他を指定）

DCTAMER_NOREC（01731）

dc_tam_read（更新目的の入力）

DCTAMER_NOREC（01731）

dc_tam_read_cancel（入力の取り消し）

DCTAMER_NOREC（01731）

dc_tam_rewrite（入力前提の更新）

DCTAMER_NOREC（01731）※3

dc_tam_write（更新）

DCTAMER_NOREC（01731）

dc_tam_write（追加）

○

dc_tam_delete（削除）

DCTAMER_NOREC（01731）

（凡例）

○：エラーになりません。

DCTAMER_NOREC（01731）：指定されたレコードはありません。

DCTAMER_SEQENCE（01732）：dc_tam_read関数を呼び出していません。

DCTAMER_EXKEY（01735）：関数に設定したキー値のレコードがあるので，追加できません。

注※1

dc_tam_read関数（参照目的の入力，排他を指定）の前に，dc_tam_rewrite関数，dc_tam_write関数を呼び出して，レコードを更新または追加されている場合は，DCTAMER_EXREWRT，またはDCTAMER_EXWRITEがリターンされます。

注※2

dc_tam_read_cancel関数（入力の取り消し）の前にdc_tam_rewrite関数，dc_tam_write関数を呼び出して，レコードを更新または追加されている場合は，DCTAMER_EXWRITEがリターンされます。

注※3

dc_tam_delete関数（削除）の前にdc_tam_write関数を呼び出して，レコードが追加されている場合は，DCTAMER_SEQENCEがリターンされます。

表4‒8　同じレコードに対して関数を複数回呼び出したときの処理結果（異なるグローバルトランザクション）

前回呼び出した関数

今回呼び出した関数

結果またはエラーリターンする値

トランザクション内で，まだTAMテーブルにアクセスする関数を呼び出していない

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○

dc_tam_read（更新目的の入力）

○

dc_tam_read_cancel（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

○

dc_tam_write（追加）

○

dc_tam_delete（削除）

○

dc_tam_read

（参照目的の入力）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○※2

dc_tam_read（更新目的の入力）

○※2

dc_tam_read_cancel（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

○※2

dc_tam_write（追加）

DCTAMER_EXKEY（01735）

dc_tam_delete（削除）

○※2

dc_tam_read

（参照目的の入力　排他を指定）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○※2

dc_tam_read（更新目的の入力）

DCTAMER_LOCK（01736）※3

dc_tam_read_cancel（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

DCTAMER_LOCK（01736）※3

dc_tam_write（追加）

DCTAMER_LOCK（01736）※3

dc_tam_delete（削除）

DCTAMER_LOCK（01736）※3

dc_tam_read

（更新目的の入力）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

DCTAMER_LOCK（01736）※3

dc_tam_read（更新目的の入力）

DCTAMER_LOCK（01736）※3

dc_tam_read_cancel

（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

DCTAMER_LOCK（01736）※3

dc_tam_write（追加）

DCTAMER_LOCK（01736）※3

dc_tam_delete（削除）

DCTAMER_LOCK（01736）※3

dc_tam_read_cancel

（入力の取り消し）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

○※4，※5

dc_tam_read（更新目的の入力）

○※4，※5

dc_tam_read_cancel

（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

○※4，※5

dc_tam_write（追加）

DCTAMER_LOCK（01736）※3

dc_tam_delete（削除）

DCTAMER_LOCK（01736）※3

dc_tam_rewrite

（入力前提の更新）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

DCTAMER_LOCK（01736）※3

dc_tam_read（更新目的の入力）

DCTAMER_LOCK（01736）※3

dc_tam_read_cancel

（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

DCTAMER_LOCK（01736）※3

dc_tam_write（追加）

DCTAMER_LOCK（01736）※3

dc_tam_delete（削除）

DCTAMER_LOCK（01736）※3

dc_tam_write

（更新，または追加）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

DCTAMER_LOCK（01736）※3

dc_tam_read（更新目的の入力）

DCTAMER_LOCK（01736）※3

dc_tam_read_cancel

（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

DCTAMER_LOCK（01736）※3

dc_tam_write（追加）

DCTAMER_LOCK（01736）※3

dc_tam_delete（削除）

DCTAMER_LOCK（01736）※3

dc_tam_delete

（削除）

dc_tam_read（参照目的の入力）

○

dc_tam_read（参照目的の入力　排他を指定）

DCTAMER_LOCK（01736）※3

dc_tam_read（更新目的の入力）

DCTAMER_LOCK（01736）※3

dc_tam_read_cancel（入力の取り消し）

−※1

dc_tam_rewrite（入力前提の更新）

−※1

dc_tam_write（更新）

DCTAMER_LOCK（01736）※3

dc_tam_write（追加）

DCTAMER_LOCK（01736）※3

dc_tam_delete（削除）

DCTAMER_LOCK（01736）※3

（凡例）

○：エラーになりません。

−：該当しません。

DCTAMER_EXKEY（01735）：関数に設定したキー値のレコードがあるので，追加できません。

DCTAMER_LOCK（01736）：排他エラーが起こりました。

注※1

異なるトランザクションでは，別の処理になります。

注※2

別グローバルトランザクションで，同じTAMテーブルに対してレコードの追加／削除している場合は，DCTAMER_LOCK（01736）がリターンされます。ただし，排他待ち種別にDCTAM_WAITを設定した場合は，排他解除待ちとなります。

注※3

排他待ち種別にDCTAM_WAITを設定した場合は，排他待ちとなります。

注※4

別グローバルトランザクションでレコードの追加／削除している場合は，DCTAMER_LOCK（01736）がリターンされます。ただし，排他待ち種別にDCTAM_WAITを設定した場合は，排他解除待ちとなります。

注※5

dc_tam_read_cancel関数の前に，別グローバルトランザクションで，dc_tam_rewrite関数，dc_tam_write関数を呼び出して，レコードの更新または追加している場合は，DCTAMER_LOCK（01736）がリターンされます。ただし，排他待ち種別にDCTAM_WAITを設定した場合は，排他解除待ちとなります。

4.2.6　TAMテーブルの排他制御

TAMテーブルの更新中に，ほかのUAPからのTAMテーブルを更新する処理が割り込むと，一つのレコードに二つの処理が同時に反映されて，テーブルの内容に矛盾が生じます。これを防ぐためにTAMテーブルにアクセスする関数内に排他制御の指定をします。排他制御することで，複数のUAPからアクセスされる各データ間の整合性が保証されます。

TAMテーブルはグローバルトランザクション単位に排他制御します。

(1)　排他制御モード

TAMテーブルアクセス時の排他の条件を排他制御モードといいます。排他制御モードには次の2種類があります。

参照目的の排他（共用モード　PR　Protected Retrieve）

排他したレコードの参照だけできます。ほかのグローバルトランザクションからの参照だけを許可します。

更新目的の排他（排他モード　EX　EXclusive）

排他したレコードまたはテーブルの参照，更新ができます。ほかのグローバルトランザクションからの参照，更新を禁止します。

(2)　排他の指定単位

オンライン中のTAMテーブルへアクセスするときの排他の指定単位には，次の2種類があります。

(a)　レコード排他

レコード単位に排他制御します。レコードを参照目的で入力するときは，参照目的の排他をするか，または排他をしない（ほかのUAPに更新を許す）設定をします。更新目的の入力や更新では，更新目的の排他をします。確保された排他は，TAMテーブルへの処理を指定したトランザクションが終了したときに解除されます。

(b)　テーブル排他

テーブル単位に排他制御します。TAMテーブルをテーブル排他でオープン時，およびレコードの追加/削除をしたときに，TAMテーブル全体に対して更新目的の排他をします。確保された排他は，TAMテーブルへの処理を指定したトランザクションが終了したときに解除されます。トランザクションを開始する前にオープンした場合は，テーブル排他はできません。

(3)　資源の排他解除待ちの設定

アクセスしようとしたTAMテーブルがすでにほかのUAPから排他を掛けられていた場合（排他エラー）に，アクセスした関数をエラーリターンするか，排他が解除されるのを待つかを，関数の引数に指定できます。

排他が解除されるのを待つと設定した場合に，デッドロックやタイムアウトが起こったときは，排他の解除を待っている関数がエラーリターンして，デッドロック情報が出力されます。デッドロックやタイムアウトで関数がエラーリターンした場合は，トランザクションの同期点を取得して，確保した資源をすべて解放してください。

COBOL言語で作成したUAPの場合，排他が解除されるのを待つかどうかを，次に示すどちらかで指定します。

TAMサービス定義のtam_cbl_levelオペランド

COBOL-UAP作成用プログラムCBLDCTAMのデータ名Iの設定

COBOL言語のUAPの場合に排他解除待ちを指定する方法については，マニュアル「OpenTP1 システム定義」および「OpenTP1 プログラム作成リファレンス COBOL言語編」を参照してください。

TAMサービスの関数の排他指定と実際に排他される状態を次の表に示します。

COBOL言語のUAPの場合は，レコードへアクセスするAPIで排他を確保します。

表4‒9　TAMサービスの関数の排他指定と実際に排他される状態

TAMサービスの関数とフラグに設定した値

TAMテーブルへの排他

TAMレコードへの排他

dc_tam_open関数

テーブル排他

更新排他

−※1

レコード排他

レコードにアクセスする関数で排他を確保

dc_tam_read関数

CBLDCTAM('FxxR'/'FxxU'/'VxxR'/'VxxU')

参照目的

('FxxR'/'VxxR')

排他なし

−

−

排他あり

参照排他※2

参照排他

更新目的

(FxxU'/'VxxU')

参照排他※2

更新排他

dc_tam_rewrite関数

参照排他※3

更新排他※3

dc_tam_write関数

CBLDCTAM('MFY '/'MFYS'/'STR '/'WFY '/'WFYS'/'YTR ')

更新目的

('MFY '/'WFY ')

参照排他※2

更新排他

「更新または追加」('MFYS'/'WFYS')または「追加」('STR '/'YTR ')目的

更新排他

−※1

dc_tam_delete関数

CBLDCTAM('ERS '/'ERSR'/'ZRS '/'ZRSR')

更新排他

−※1

（凡例）

−：該当しません。

注※1

テーブル全体が更新排他で確保されるため，ほかのトランザクションからはアクセスできません。

注※2

「参照型」または「追加・削除できない更新型」のテーブルでは，TAMサービス定義でテーブル排他モードを「排他しない」とした場合は，この排他は確保されません。

注※3

更新目的のdc_tam_read関数で，すでに資源は確保されています。

(4)　排他なし参照使用時の注意事項

レコード単位の排他制御ではレコードを参照目的で入力するときに排他をしない設定（排他なし参照）が選択できます。排他なし参照は，ほかのUAPからのアクセス状態に関係なくTAMアクセスができるので，性能を重視したい場合には有効な手段となります。ただし，使用に際しては特に次の点に注意してください。

排他制御を行わないので，同一データに対して参照と更新が競合する可能性のある業務には適しません。

UAPからの更新結果が共用メモリ上のTAMテーブルに反映されるのは，更新を行ったUAPのコミット完了の時点です。それまでは，ほかのUAPからは更新前のデータしか見ることができません。

その一例を次に示します。

図4‒8　更新後の情報が排他なし参照時に反映されない例

(1)UAP1よりTAMの更新を行う

(2)UAP1よりdc_mcf_execapでUAP2（MHP）を起動する

(3)UAP2から，(1)で更新したTAMの情報を参照する（排他なし参照）

この場合，(3)のタイミングでは(1)の更新結果が共用メモリ上のTAMテーブルに反映されている保証はありません。UAP2が更新後の情報を期待しているようなアプリケーション設計を行うと処理不正となる可能性があります。

したがって，このような場合には，(3)では排他ありの参照を行う必要があります。

4.2.7　テーブル排他なしTAMテーブルアクセス機能

TP1/FS/Table Access　05-00以前では，レコードを追加または削除する場合，テーブル単位の排他を確保します。これをテーブル排他ありTAMテーブルアクセス機能といいます。テーブル単位の排他については，「4.2.6　TAMテーブルの排他制御」を参照してください。

TP1/FS/Table Access　05-01以降では，テーブル単位の排他を確保しないで，レコード単位の排他資源だけを確保して，TAMテーブルのレコードにアクセスできます。これをテーブル排他なしTAMテーブルアクセス機能といいます。

(1)　テーブル排他なしTAMテーブルアクセス機能の使用方法

テーブル排他なしTAMテーブルアクセス機能を使用するときは，TAMテーブルのアクセス形態に，「テーブル排他を確保しない，追加・削除できる更新型」を指定します。アクセス形態は，TAMサービス定義のtamtableコマンド定義句またはtamaddコマンドで指定してください。tamtableコマンド定義句については，マニュアル「OpenTP1 システム定義」を，tamaddコマンドについてはマニュアル「OpenTP1 運用と操作」を参照してください。

同じOpenTP1システムで，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルと，テーブル排他ありTAMテーブルアクセス機能を使用するTAMテーブルを混在できます。

テーブル排他なしTAMテーブルアクセス機能を使用するときに，既存のTAMファイルをtamcreコマンドによって再作成する必要はありません。

(2)　排他制御

(a)　排他の確保と解放

dc_tam_open関数およびレコードにアクセスする関数（dc_tam_read，dc_tam_write，dc_tam_delete）で排他をします。COBOL言語のUAPの場合は，レコードへアクセスするプログラムで排他をします。

確保された排他は，TAMテーブルにアクセスしたトランザクションが終了したときに解放されます。

(b)　テーブル排他なしTAMテーブルアクセス機能でのTAMサービスの関数の排他指定と実際に排他される状態

テーブル排他なしTAMテーブルアクセス機能でのTAMサービスの関数の排他指定と実際に排他される状態を次の表に示します。

表4‒10　テーブル排他なしTAMテーブルアクセス機能でのTAMサービスの関数の排他指定と実際に排他される状態

TAMサービスの関数とフラグに指定した値

テーブル排他

レコード排他

dc_tam_open関数

テーブル排他

更新排他※1

−

レコード排他

−

−

dc_tam_read関数

参照目的

排他なし

−

−

排他あり

−

参照排他

更新目的

−

更新排他

dc_tam_rewrite関数

−

更新排他※2

dc_tam_write関数

−

更新排他

dc_tam_delete関数

−

更新排他

（凡例）

−：排他を確保しません。

注※1

テーブル排他指定のdc_tam_open関数は，ほかのトランザクションのテーブル排他指定のdc_tam_open関数とだけ排他で待ち合わせ，レコードにアクセスする関数とは待ち合わせをしません。詳細は，「4.2.7(3)　注意事項」を参照してください。

注※2

dc_tam_rewrite関数では排他を確保しませんが，更新目的のdc_tam_read関数で，すでに排他は確保されています。

(c)　排他の確保処理

テーブル排他ありTAMテーブルアクセス機能と，テーブル排他なしTAMテーブルアクセス機能の，レコード更新時の排他確保処理を次の図に示します。

図4‒9　レコード更新時の排他確保処理

テーブル排他ありTAMテーブルアクセス機能では，dc_tam_writeで，この図の(1)(2)(3)に示すように参照目的のテーブル排他を確保し，更新目的のレコード排他を確保して，レコードを更新します。

テーブル排他なしTAMテーブルアクセス機能では，dc_tam_writeで，この図の(4)(5)に示すように更新目的のレコード排他を確保して，レコードを更新します。

テーブル排他ありTAMテーブルアクセス機能とテーブル排他なしTAMテーブルアクセス機能のレコード追加時の排他確保処理を次の図に示します。

図4‒10　レコード追加時の排他確保処理

テーブル排他ありTAMテーブルアクセス機能では，dc_tam_writeで，この図の(1)(2)に示すように更新目的のテーブル排他を確保して，レコードを追加します。

テーブル排他なしTAMテーブルアクセス機能では，dc_tam_writeで，この図の(3)(4)に示すように，更新目的のレコード排他を確保して，レコードを追加します。

このように，テーブル排他なしTAMテーブルアクセス機能とテーブル排他ありTAMテーブルアクセス機能では排他の確保処理が異なるため，トランザクション間でTAMテーブルへのアクセスが競合した場合の動作も異なります。テーブル排他ありTAMテーブルアクセス機能では，レコードを追加または削除するトランザクションが存在すると，ほかのトランザクションからは同じTAMテーブルに対してレコードを参照（排他あり），更新，追加，および削除できません。テーブル排他なしTAMテーブルアクセス機能では，アクセスするレコードが競合しなければ，同じTAMテーブルにアクセスできます。

テーブル排他ありTAMテーブルアクセス機能で，レコードアクセスが競合した場合の処理を次の図に示します。

図4‒11　テーブル排他ありTAMテーブルアクセス機能でレコードアクセスが競合した場合の処理

UAP1がレコード1を追加するとします。UAP1では，この図の(1)(2)に示すように，更新目的のテーブル排他を確保して，レコードを追加します。

UAP2では，この図の(3)に示すように，参照目的のテーブル排他を確保できないため，レコード3を更新できません。

UAP3では，この図の(4)に示すように，更新目的のテーブル排他を確保できないため，レコード5を追加できません。

このため，UAP2およびUAP3は，UAP1のトランザクションが決着して排他が解放されるまで待つか，またはDCTAMER_LOCKで異常終了します。

テーブル排他なしTAMテーブルアクセス機能で，レコードアクセスが競合した場合の処理を次の図に示します。

図4‒12　テーブル排他なしTAMテーブルアクセス機能でレコードアクセスが競合した場合の処理

UAP1がレコード1を追加するとします。UAP1では，この図の(1)(2)に示すように，レコード1に対して更新目的のレコード排他を確保して，レコードを追加します。

UAP2では，この図の(3)に示すように，レコード3に対して更新目的のレコード排他を確保して，レコード3を更新します。

UAP3では，この図の(4)に示すように，レコード5に対して更新目的のレコード排他を確保して，レコード5を追加します。

以上のように，テーブル排他を確保しないため，UAP1のトランザクションが決着していない状態でも，UAP2およびUAP3は同じTAMテーブルにアクセスできます。

(3)　注意事項

テーブル排他なしTAMテーブルアクセス機能を使用する場合，次の点に注意してください。

(a)　dc_tam_open関数のテーブル排他

dc_tam_open関数をテーブル排他指定（flagsにDCTAM_TBL_EXCLUSIVEを指定）で発行した場合，dc_tam_open関数内でテーブル排他を確保しますが，レコードにアクセスする関数（dc_tam_read，dc_tam_write，dc_tam_delete）との排他制御はしません。つまり，テーブル排他指定のdc_tam_open関数同士はテーブル排他で待ち合わせをしますが，テーブル排他指定のdc_tam_open関数とレコードにアクセスする関数の間では排他の待ち合わせをしません。

dc_tam_open関数の排他方式を次の図に示します。

図4‒13　dc_tam_open関数の排他方式

UAP1では，dc_tam_open関数をテーブル排他指定（flagsにDCTAM_TBL_EXCLUSIVEを指定）で発行し，この図の(1)に示す更新目的のテーブル排他を確保します。

UAP2では，テーブル排他指定でdc_tam_open関数を発行しますが，この図の(2)に示すように，更新目的のテーブル排他が確保できないため，UAP1のトランザクションが決着して排他が解放されるまで待つか，またはDCTAMER_LOCKで異常終了します。

UAP3では，レコード排他指定（flagsにDCTAM_REC_EXCLUSIVEを指定）でdc_tam_open関数を発行しているため，dc_tam_open関数は正常終了します。レコード3の更新では，この図の(3)に示すように，レコード3に対して更新目的のレコード排他を確保して，レコード3を更新します。

(b)　レコード追加時の空きレコードの割り当て

レコードの削除をした場合，レコードを削除したトランザクションがコミットするまで，削除したレコードは空きレコードにはなりません。そのため，レコードを削除したトランザクションがコミットするまで，削除したレコードの領域は追加するレコードに割り当てられません。ただし，レコードを削除したトランザクションと同一トランザクション内で，キー値が同じレコードを追加する場合には，削除したレコードの領域が割り当てられます。

したがって，追加するレコード数分の空きレコードがない状態でレコードを追加する場合，追加するトランザクションと同じトランザクションで異なるキー値のレコードを削除しても，レコードの追加はDCTAMER_NOAREAでエラーリターンします。

レコードの追加がDCTAMER_NOAREAとなる例を次の図に示します。

図4‒14　レコードの追加がDCTAMER_NOAREAとなる例

最大レコード数が3のTAMテーブルにキー値1，キー値2，およびキー値3のレコードが格納されているとします。UAP1では，キー値1，キー値2，キー値3を削除し，キー値4を追加します。

キー値1の削除では，この図の(1)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値2の削除では，この図の(2)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値3の削除では，この図の(3)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値4の追加では，この図の(4)に示すように，空きレコードがないため，DCTAMER_NOAREAでエラーリターンします。

レコードの追加がDCTAMER_NOAREAとならないようにするには，追加するレコード数分の空きレコードを用意するか，またはレコードを削除したトランザクションをコミットしたあとでレコードを追加する必要があります。

追加するレコード数分の空きレコードを用意する場合の処理を次の図に示します。

図4‒15　追加するレコード数分の空きレコードを用意する場合の処理

TAMテーブルの最大レコード数を4に増やします。TAMテーブルには，キー値1，キー値2，およびキー値3のレコードが格納されているとします。UAP1では，キー値1，キー値2，キー値3を削除し，キー値4を追加します。

キー値1の削除では，この図の(1)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値2の削除では，この図の(2)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値3の削除では，この図の(3)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値4の追加では，この図の(4)に示すように，空きレコードであるレコード4に追加できます。

レコードを削除したトランザクションをコミットしたあとでレコードを追加する場合の処理を次の図に示します。

図4‒16　レコードを削除したトランザクションをコミットしたあとでレコードを追加する場合の処理

最大レコード数が3のTAMテーブルにキー値1，キー値2，およびキー値3のレコードが格納されているとします。UAP1では，キー値1，キー値2，キー値3を削除したあとでいったんコミットし，次のトランザクションでキー値4を追加します。

キー値1の削除では，この図の(1)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値2の削除では，この図の(2)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

キー値3の削除では，この図の(3)に示すように，レコード1は削除中になりますが，空きレコードにはなりません。

コミットでは，この図の(4)に示すように，削除中のレコード1，レコード2，レコード3を空きレコードにします。

キー値4の追加では，この図の(5)に示すように，空きレコードであるレコード1に追加できます。

(c)　アクセス形態の変更

tamaddコマンドによって，テーブル排他ありTAMテーブルアクセス機能を使用するTAMテーブルから，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルに変更したり，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルから，テーブル排他ありTAMテーブルアクセス機能を使用するTAMテーブルに変更したりすることはできません。変更した場合，tamaddコマンドは異常終了します。

テーブル排他ありTAMテーブルアクセス機能を使用するか，テーブル排他なしTAMテーブルアクセス機能を使用するかを変更する場合は，TAMサービス定義のtamtableコマンド定義句を変更してOpenTP1システムを正常開始するか，TAMサービス定義に登録しないでOpenTP1システムを正常開始してtamaddコマンドで新規登録して変更してください。

(d)　デッドロック

テーブル排他ありTAMテーブルアクセス機能を使用していたTAMテーブルを，テーブル排他なしTAMテーブルアクセス機能を使用するように変更する場合，デッドロックとなることがあります。詳細は，「4.2.11(1)(b)　テーブル排他なしTAMテーブルアクセス機能を使用している場合」を参照してください。

(4)　プログラムインタフェース

dc_tam_status関数およびCBLDCTAM('INFO ')以外は，テーブル排他ありTAMテーブルアクセス機能と同じプログラムインタフェースを使用してTAMテーブルにアクセスできます。

なお，UAPは，リコンパイルまたは再リンケージが必要となることがあります。リコンパイルが必要な条件を表4-11に，再リンケージが必要な条件を表4-12に示します。

表4‒11　リコンパイルが必要な条件

条件

必要な作業

dc_tam_status使用

あり

st_acs_type参照

あり

アクセス形態の情報として，新定数DCTAM_STS_RECLCKが返却されるので，UAPを修正し，リコンパイルし直す必要があります。

なし

リコンパイルは不要です。

なし

表4‒12　再リンケージが必要な条件

条件

必要な作業

AP使用ライブラリ

アーカイブライブラリ

再リンケージが必要です。

共用ライブラリ

再リンケージは不要です。

dc_tam_status関数では，DC_TAMSTAT構造体のst_acs_typeにアクセス形態を返却します。このst_acs_typeに返却する値にDCTAM_STS_RECLCKを追加します。DCTAM_STS_RECLCKは，「テーブル排他を確保しない，追加・削除できる更新型」というアクセス形態を表し，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルであることを意味します。

dc_tam_status関数のそのほかの返却値および使用方法については，マニュアル「OpenTP1 プログラム作成リファレンス C言語編」を参照してください。

CBLDCTAM('INFO ')では，データ名Kにアクセス形態を返却します。このデータ名Kに返却する値にVALUE 'L'を追加します。VALUE 'L'は，「テーブル排他を確保しない，追加・削除できる更新型」というアクセス形態を表し，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルであることを意味します。CBLDCTAM('INFO ')のそのほかの返却値および使用方法については，マニュアル「OpenTP1 プログラム作成リファレンス COBOL言語編」を参照してください。

(5)　定義インタフェース

TAMサービス定義のtamtableコマンド定義句では，-aオプションにアクセス形態を指定します。テーブル排他なしTAMテーブルアクセス機能を使用する場合，この-aオプションのオプション引数にreclckを指定してください。reclckは，「テーブル排他を確保しない，追加・削除できる更新型」というアクセス形態を表し，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルであることを意味します。

tamtableコマンド定義句のそのほかのオプションおよび使用方法については，マニュアル「OpenTP1 システム定義」を参照してください。

4.2.8　TAMファイルの作成

OpenTP1ファイルシステムに任意の直接編成ファイルを割り当てたあとに，tamcreコマンドで，TAMファイルを作成します。このとき，インデクス種別，キー領域，レコードデータなどの指定をします。

4.2.9　TAMサービスとDAMサービスとの互換

(1)　TAMテーブルにアクセスできるDAMサービスの関数

DAMファイルサービスの関数（dc_dam_〜）で，TAMテーブルのレコードにアクセスできます。この場合は，DAMファイルでの論理ファイル名をTAMテーブル名として扱い，DAMファイルでの相対ブロック番号をTAMテーブルのキー値として扱います。TAMテーブルにアクセスできるDAMサービスの関数は次のとおりです。

dc_dam_open関数（論理ファイルのオープン）

dc_dam_close関数（論理ファイルのクローズ）

dc_dam_read関数（論理ファイルのブロックの入力）

dc_dam_rewrite関数（論理ファイルのブロックの更新）

dc_dam_write関数（論理ファイルのブロックの出力）

dc_dam_hold関数（論理ファイルの閉塞），dc_dam_release関数（論理ファイルの閉塞解除）をTAMテーブルに対して呼び出した場合は正常にリターンしますが，実際には閉塞／閉塞解除されません。

DAMサービスの関数のうち，TAMファイルのレコードにアクセスできない関数を次に示します。

オフラインの業務で使う関数すべて

dc_dam_start関数（回復対象外DAMファイルの使用の開始）

dc_dam_end関数（回復対象外DAMファイルの使用の終了）

dc_dam_status関数（論理ファイルの状態の参照）

(2)　DAMファイルのデータを読み込んで，TAMアクセスできるようにする方法

DAMファイルをTAMアクセスできるようにするには，次の手順でファイルを変更します。

dc_dam_get関数でDAMファイルのデータを入力して，各データにキー値を付けたあとに，任意のファイルに格納する。

1.のファイルを入力として，tamcreコマンドを実行してTAMファイルを作成する。

4.2.10　TAMサービスの統計情報

TAMサービスで取得するトランザクション単位の統計情報は，グローバルトランザクション単位に取得します。したがって，統計情報を出力するかどうかは，ルートトランザクションブランチのユーザサービス定義に指定した値に従います。

4.2.11　TAMのレコード追加・削除に伴う注意事項

排他確保によるデッドロックを発生させないためには，各UAPで確保する資源に対する排他の種類・順序を整理する必要があります。ここでは，TAMレコードの追加・削除に伴う排他確保によるデッドロックの発生と注意について説明します。

(1)　トランザクションのデッドロック要因

(a)　テーブル排他ありTAMテーブルアクセス機能を使用している場合

「追加削除できる更新型」のTAMテーブルで，同一トランザクション内で同一テーブルに対して「追加（削除），およびその他TAMアクセス」を行う場合は，このトランザクションがデッドロックの要因になる可能性があります。これは次の要因を満たす場合です。

同一トランザクション内で同一テーブルに対して「追加（削除），およびその他TAMアクセス（排他あり）」を行う。

「追加（削除），およびその他TAMアクセス」のアクセス順序が次のようになった場合

「その他TAMアクセス」→「追加（削除）」

TAMテーブルのオープンが次のどちらかの場合

トランザクション外

トランザクション内でレコード排他（COBOL言語の場合はこのタイプ）

上記トランザクションと同時に，排他確保の必要がある別トランザクションが同一テーブルにアクセスする。

(b)　テーブル排他なしTAMテーブルアクセス機能を使用している場合

テーブル排他ありTAMテーブルアクセス機能でレコードを更新，追加，または削除していたTAMテーブルを，テーブル排他なしTAMテーブルアクセス機能を使用するように変更する場合，デッドロックとなることがあります。

テーブル排他ありTAMテーブルアクセス機能でレコードを更新，追加，または削除する場合，更新排他でテーブル排他を確保します。このため，追加または削除するレコードの順序が同じレコードにアクセスするほかのトランザクションと異なっていても，テーブル排他で待ち合わせているのでデッドロックにはなりません。しかし，テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルではデッドロックとなることがあります。このため，テーブル排他ありTAMテーブルアクセス機能でレコードを更新，追加，または削除していたTAMテーブルを，テーブル排他なしTAMテーブルアクセス機能を使用するように変更する場合，UAPでアクセスするレコードの順序を統一してください。

テーブル排他ありTAMテーブルアクセス機能からテーブル排他なしTAMテーブルアクセス機能に変更してデッドロックとなる例を次の図に示します。

図4‒17　テーブル排他ありTAMテーブルアクセス機能からテーブル排他なしTAMテーブルアクセス機能に変更してデッドロックとなる例

UAP1では，レコード1，レコード3の順に削除し，UAP2では，レコード3，レコード1の順に更新するとします。テーブル排他ありTAMテーブルアクセス機能もテーブル排他なしTAMテーブルアクセス機能も図の(1)〜(4)の順に実行されるとします。

テーブル排他ありTAMテーブルアクセス機能では，次の手順で動作します。

UAP1のレコード1の削除で，更新目的のテーブル排他を確保します。

UAP2のレコード3の更新では，手順1と排他の競合が発生し，参照目的のテーブル排他の確保で排他解除待ちとなります。

UAP1のレコード3の削除では，排他は確保しません。

UAP1のトランザクションが決着することによって手順1で確保した排他が解放されると，手順2の排他解除待ちが解けてUAP2の処理が実行できます。

UAP1のトランザクションが決着したあと，UAP2の手順2では参照目的のテーブル排他と更新目的のレコード排他を確保し，手順4のレコード1の更新では，更新目的のレコード排他を確保します。

テーブル排他なしTAMテーブルアクセス機能では，次の手順で動作します。

UAP1のレコード1の削除で，更新目的のレコード排他を確保します。

UAP2のレコード3の更新で，更新目的のレコード排他を確保します。

UAP1のレコード3の削除では，手順2と排他の競合が発生し，更新目的のレコード排他の確保で排他解除待ちとなります。

UAP2のレコード1の更新では，手順1と排他の競合が発生し，更新目的のレコード排他の確保で排他解除待ちとなり，デッドロックが発生します。

デッドロックを回避するには，UAP1の手順1と手順3の順序を入れ替えるか，または，UAP2の手順2と手順4の順序を入れ替えます。

(2)　排他確保の流れ

同一トランザクション内で同一テーブルに対する排他確保の様子を，レコードの「更新＋追加」という処理を例に説明します。

更新および追加の目的の排他確保の例を次の図に示します。

図4‒18　「更新＋追加」の例

更新目的のdc_tam_writeで，この図の(1)，(2)に示す排他を確保してレコードを更新します。

目的のレコードは，「追加削除できる更新型」TAMテーブルにあります。このトランザクションが終了するまで，テーブル内のレコード構成を別トランザクションに変更させないために，テーブル全体に参照排他（PR）を確保します。

次に，追加目的のdc_tam_writeで，この図の(3)に示す排他を確保してレコードを追加します。

テーブル内の構成を変更するので，このトランザクションが終了するまでテーブルを別トランザクションに参照させないために，テーブル全体に更新排他（EX）を確保します。

1.から2.の一連の処理の中で，テーブルに対する排他を「参照排他（PR）」から「更新排他（EX）」に変更しようとすることになります。

1.から2.の処理の間で，デッドロックが発生する流れを次の図に示します。

図4‒19　デッドロック発生

1.の処理のあとでかつ2.の処理が行われる前であれば，別トランザクションは同一テーブルに対してこの図の(2)-1に示すように参照排他（PR）を確保できます。このとき，別トランザクションが，本トランザクションで更新したレコードを排他確保しようとすると，テーブルに対して参照排他（PR）を確保したままレコードの排他解除待ちになります（この図の(2)-2）。

その後，2.の処理が行われると，別トランザクションが同一テーブルに対して参照排他（PR）を確保しているために，テーブルに対して更新排他（EX）を確保できないで排他解除待ちになります。

3.によって，二つのトランザクションがお互いの排他資源の解除待ちになり，デッドロックとなります。

この図では，自トランザクション内の追加の処理で必要になるはずの資源（テーブル）の更新排他（EX）を確保しないで処理（2.の手前までの処理）を進め，別トランザクションにテーブルの排他確保を許してしまったためにデッドロックとなりました。あらかじめテーブルに対して更新排他（EX）を確保していれば，別トランザクションにテーブルの排他を確保させることはありません。

このため，同一トランザクション内では同一テーブルに対して「追加（削除）およびその他TAMアクセス」を行わないようにするなど，「(1)　トランザクションのデッドロック要因」を満たさないようにしてください。

(3)　デッドロックを避けるための注意

同一トランザクション内では同一テーブルに対して「追加（削除）およびその他TAMアクセス」を行う必要があり，上記のようなデッドロックの危険がある場合は，該当するトランザクションでテーブルに対して更新排他（EX）を確保してから処理をするようにしてください。

テーブルに対して更新排他を確保するためには，「追加（削除）」を先に行うか，またはC言語であればテーブルに対してトランザクション内でテーブル排他でオープンするようにしてください。

4.3　ISTサービス（TP1/Shared Table Access）

複数のOpenTP1システムが，ノードをわたってテーブルを共用できる機能をISTサービスといいます。ISTサービスで使えるテーブルをISTテーブルといいます。ISTサービスを使うと，テーブルの実体がどのノードにあるかを意識しないで，UAPからデータを参照，更新できます。さらに，各ノードの業務状態を管理するために，メールとしてISTテーブルを使うこともできます。ただし，複数のノードにわたってデータを配布させる場合，次に示す条件の業務にはISTサービスはお勧めできません。

データを即時に配布する必要がある業務

大量のデータを扱う必要がある業務

頻繁にデータを更新する業務

ISTテーブルを使う場合，各ノードのシステムにTP1/Shared Table Accessが組み込まれていることが前提となります。また，OpenTP1の基本機能がTP1/Server Baseの場合だけ，ISTサービスを使えます。TP1/LiNKではISTサービスを使えません。

4.3.1　ISTサービスのシステム構成

ISTサービスを使用するには，ノード間のISTテーブル定義の指定を合わせてください。ノード間でISTテーブル定義の指定を合わせないと，KFCA25533-Wメッセージが出力されます。ノード間でISTテーブル定義の指定が不一致の場合の例を次の図に示します。

図4‒20　ノード間でISTテーブル定義の指定が不一致の場合

この図の場合，ノードA，ノードB，およびノードCでISTテーブル定義に指定したテーブル名が合っていないため，予期しないテーブル情報を受信したとして，ノードAおよびノードBで，OpenTP1が終了するまで定期的にKFCA25533-Wメッセージを出力し続けます。

4.3.2　ISTテーブルの概要

ISTテーブルの概要について説明します。

(1)　ISTテーブルへのアクセス環境

ISTテーブルは，各ノードの共用メモリ上にあるテーブルです。テーブルの実体にあたるファイルはありません。そのため，UAPからISTテーブルへアクセスできるのは，オンライン中だけです。オフライン環境ではISTテーブルにはアクセスできません。

また，複数のノードでISTサービスを使う場合には，各ノードの時刻を合わせておく必要があります。ノード間で時刻が一致していないと，あるノードで更新したデータに対して，別のノードからの更新が反映されないことがあります。ISTサービスで複数のノードのISTレコード（ISTテーブル中のレコード）を更新する処理の流れを次の図に示します。

図4‒21　ISTレコードの更新処理

ノードAのISTテーブルAのISTレコード（レコード番号1）を更新するレコード更新データを作成します。

現在の時刻（マシン時刻：マイクロ秒精度）を取得し，レコード更新データにタイムスタンプとして付与します。

ノードAの共用メモリ上の該当するISTレコードに設定されているタイムスタンプとレコード更新データに付与したタイムスタンプとを比較します。

レコード更新データの方が新しい場合は，共用メモリ上のISTレコードを更新します。レコード更新データの方が古い場合は，共用メモリ上のISTレコードを更新しません。なお，ISTレコードを更新しない場合も，dc_ist_write関数は正常にリターンします。

共用メモリ上のISTレコードを更新した場合，ノードAでISTレコードを更新したことをノードBのISTサービスへ通知します。このとき，ISTレコードとISTレコードに付与したタイムスタンプも通知します。

更新されたISTレコードを受信したノードBのISTサービスは，ノード内の該当するISTレコードに設定されているタイムスタンプと受信したISTレコードのタイムスタンプとを比較します。

5.の結果，受信したISTレコードのタイムスタンプの方が新しいと判断した場合だけ，ノードBの該当するISTレコードを，受信したISTレコードの情報に更新します。

上記のように，ISTサービスでは，ISTレコードを更新するか，またはそのままとするかを，タイムスタンプを基に判断しています。次のような場合は，最新の更新データがISTレコードに反映されないことがあります。

ノードAのマシン時刻がノードBのマシン時刻よりも進んでいる場合

ノードAでISTレコードを更新したあとに，ノードBから同一のISTレコードの更新を通知されても，ノードAのISTレコードに設定されたタイムスタンプの方が新しいと判断します。そのため，ノードBで更新されたISTレコードの情報がノードAのISTレコードに反映されません。

また，ノードAで更新したISTレコードをノードBへ通知したときに，通知したISTレコードのタイムスタンプの方が新しいと判断されるため，ノードBの該当するISTレコードは，実際には最新の情報であっても，通知したISTレコードの情報に更新されてしまいます。

ノードAのマシン時刻がノードBのマシン時刻よりも遅れている場合

ノードBがISTレコードを更新して，そのISTレコードの情報がすでにノードAに通知されているとき

ノードBでISTレコードを更新したあとに，ノードAで同一のISTレコードを更新しても，更新処理をしないでdc_ist_write関数が正常リターンします。

ノードBがISTレコードを更新したが，そのISTレコードの情報がまだノードAに通知されていないとき

ノードBでISTレコードを更新したあとに，ノードAで同一のISTレコードを更新すると，ノードAの更新情報で，いったんISTレコードを更新しますが，そのあとにノードBから通知されたISTレコードのタイムスタンプの方が新しいと判断するため，ノードBから通知されたISTレコードの情報を，ノードAのISTレコードに反映してしまいます。

(2)　ISTテーブルの構造

UAPからISTテーブルを参照，更新するときは，レコード単位でアクセスします。ISTテーブルは，複数のレコードから構成されます。UAPの処理では，一つのレコードへアクセスすることも，複数のレコードへ一括してアクセスすることもできます。

4.3.3　ISTテーブルへのアクセス手順

UAPからISTテーブルへアクセスするときの手順について説明します。なお，ISTテーブルへのアクセスは，トランザクションの関数でコミット，ロールバックできません。

(1)　ISTテーブルのオープン

UAPからISTテーブルにアクセスする場合は，まずISTテーブルをオープンします。ISTテーブルをオープンするときは，dc_ist_open関数【CBLDCIST('OPEN')】を呼び出します。ISTテーブルをオープンすると，テーブル記述子がリターンされます。ISTテーブルのオープン以降の処理では，テーブル記述子を関数に設定してアクセスします。テーブル記述子は，オープン以降の処理でもUAPで保持しておいてください。

(2)　レコードの参照／更新手順

ISTテーブルのレコードを入力するときは，dc_ist_read関数【CBLDCIST('READ')】を呼び出します。ISTテーブルのレコードへデータを出力するときは，dc_ist_write関数【CBLDCIST('WRIT')】を呼び出します。dc_ist_read関数，dc_ist_write関数を呼び出すときは，dc_ist_open関数でリターンされたテーブル記述子を引数に設定します。

レコードを入力または出力するときは，複数のレコードのキー値を一括して指定できます。キー値は，構造体として関数に設定します。この構造体は，複数個指定できます。

(3)　ISTテーブルのクローズ

ISTテーブルをクローズするときは，dc_ist_close関数【CBLDCIST('CLOS')】を呼び出します。dc_ist_close関数を呼び出すときは，dc_ist_open関数でリターンしたテーブル記述子を引数に設定します。

ISTテーブルへのアクセス手順を次の図に示します。

図4‒22　ISTテーブルへのアクセス手順

4.3.4　ISTテーブルの排他制御

ISTテーブルでは，UAPから呼び出した関数ごとに排他制御しています。データの入力から更新までISTテーブルを占有する制御はしていません。そのため，一つのテーブルに複数のUAPからアクセスした場合でも，デッドロックが起こることはありません。

4.4　ISAMファイルサービス（ISAM，ISAM/B）

索引順編成ファイルを管理する，ISAMファイルサービスについて説明します。機能については，マニュアル「索引順編成ファイル管理 ISAM」を参照してください。

4.4.1　ISAMファイルの概要

索引順編成ファイルは，キーを管理するインデクス部と，データを格納するデータファイル部から構成されます。キーを使用して，順処理（シーケンシャルアクセス）や乱処理（ランダムアクセス）ができます。

ISAMファイルの操作には，ライブラリ関数をUAPから呼び出す方法と，ユティリティコマンドを実行して管理する方法があります。

4.4.2　ISAMサービスの種類

OpenTP1のUAPでは，次に示すISAMファイルサービスを使えます。

ISAM

ISAM/B

ISAMは，TP1/Server BaseとTP1/LiNKで使えます。ISAM/Bは，TP1/Server Baseの場合だけ使えます。OpenTP1の基本機能がTP1/LiNKの場合は，ISAM/Bは使えません。

(1)　ISAM

ISAMファイルを，通常のファイルとして使います。OpenTP1のトランザクション処理とは同期しません。

(2)　ISAM/B

ISAMファイルをトランザクション処理と同期して使う機能です。ISAM/Bを使うと，トランザクション処理のコミット，またはロールバックで，ファイルの整合性が保てるようになります。

(a)　ISAM/Bの前提となる製品

ISAMファイルをISAM/Bとして使う場合は，ISAMに加えて，ISAMトランザクション機能（ISAM/B）が前提となります。

(b)　ファイルを作成する領域

ISAM/Bで使うISAMファイルは，OpenTP1ファイルシステムとして割り当てた領域に作成します。

(c)　OpenTP1のファイルサービス（TP1/FS/xxx）との違い

ISAM/Bでは，ロックサービスを使いません。そのため，デッドロックが起こっても，OpenTP1のロックサービス機能（優先順位による縮退やデッドロック情報の出力）は使えません。

ISAMファイルサービスの形態を次の図に示します。

図4‒23　ISAMファイルサービスの形態

4.5　データベースにアクセスする場合

OpenTP1のUAPで使うユーザファイルに，データベースマネジメントシステム（DBMS）を適用した場合について説明します。

4.5.1　OpenTP1のトランザクション処理との関係

DBMSを使う場合，X/Openで規定したDTPモデルのXAインタフェースをサポートしたDBMSかどうかで，OpenTP1のトランザクションと連携できるかどうか決まります。

(1)　XAインタフェースをサポートしたDBMSの場合

XAインタフェースをサポートしたDBMSの場合は，OpenTP1のトランザクションと同期を取って更新できます。同期を取る場合は，OpenTP1の同期点を制御する関数（dc_trn_begin関数，dc_trn_unchained_commit関数，tx_begin()，tx_commit()　など）を使います。DBMSで提供する同期点を制御する機能は，OpenTP1の同期点を制御する関数と併用できません。DBMSの同期点を制御する機能を使った場合，リソースの不整合が起こってしまう場合があります。

OpenTP1のトランザクション処理で制御できるDBMSは，XAインタフェースをサポートした製品に限ります。

XAインタフェースをサポートしている場合，複数のデータベースへアクセスするUAPでは，複数のデータベースを，整合性を保ちながら更新できます。次に示すOpenTP1のリソースマネジャは，XAインタフェースをサポートしています。

TP1/FS/Direct Access（DAMファイルサービス）

TP1/FS/Table Access（TAMファイルサービス）

ISAM，ISAM/B（ISAMファイルサービス）

TP1/Message Control（メッセージ送受信機能（MCF））

TP1/Message Queue（メッセージキューイング機能）

そのため，XAインタフェースに準拠したDBMSと，OpenTP1のリソースマネジャの両方にアクセスするUAPでも，OpenTP1のトランザクションとして処理できます。障害が原因でUAPが異常終了した場合や，OpenTP1を再開始（リラン）した場合でも，DBMSとOpenTP1リソースマネジャの両方のトランザクションを，OpenTP1で決着します。

(2)　XAインタフェースをサポートしていない，またはXAインタフェースでOpenTP1と連携していないDBMSの場合

XAインタフェースをサポートしていないDBMSの場合，DBMSへのアクセスはできますが，OpenTP1のトランザクションとは同期を取れません。

XAインタフェースでOpenTP1と連携していないため，DBMSへのアクセス中に，障害が原因でUAPが異常終了した場合や，OpenTP1を再開始（リラン）した場合には，OpenTP1からDBMSへトランザクションの決着を指示しません。そのため，DBMS独自の機能でトランザクションを回復する必要があります。

4.5.2　XAインタフェースでデータベースにアクセスする場合の準備

XAインタフェースをサポートしたDBMSを，OpenTP1とXAインタフェースで連携して使う場合に準備する項目を次に示します。この準備は，OpenTP1提供以外のリソースマネジャを使う場合に必要です。

(1)　OpenTP1への登録

OpenTP1提供以外のリソースマネジャの各種名称を登録します。OpenTP1へは，次に示すどちらかの方法で登録します。

dcsetupコマンドでOpenTP1をセットアップ後，trnlnkrmコマンドを実行する。

拡張RM登録定義を作成する。

拡張RM登録定義を作成しておくと，dcsetupコマンドでOpenTP1をセットアップしたあとにtrnlnkrmコマンドを実行しなくてもよくなります。trnlnkrmコマンドの使い方については，マニュアル「OpenTP1 運用と操作」を参照してください。拡張RM登録定義の指定方法については，マニュアル「OpenTP1 システム定義」を参照してください。

(2)　UAPのリンケージ

UAPの実行形式ファイルを作成するときに，トランザクション制御用オブジェクトファイル，およびDBMSのライブラリとオブジェクトモジュールをリンケージする必要があります。

トランザクション制御用オブジェクトファイルは，trnmkobjコマンドを実行して作成します。trnmkobjコマンドの使い方については，マニュアル「OpenTP1 運用と操作」を参照してください。

(3)　システム定義

DBMSを使う場合，トランザクションサービス定義にtrnstring形式の定義を，必要に応じてユーザサービス定義，およびユーザサービスデフォルト定義にtrnrmid形式の定義をする必要があります。指定する内容には，DBMS固有の項目もあります。このような項目は，使用するDBMSのマニュアルを参照してください。

trnstring，trnrmid形式の定義を指定すると，一つのリソースマネジャを複数の制御単位に分け，接続するユーザ名称などを変更してリソースマネジャに接続することもできます（リソースマネジャ接続先選択機能）。リソースマネジャ接続先選択機能については，「4.5.3　リソースマネジャ接続先選択機能」を参照してください。

trnstring，trnrmid形式の定義については，マニュアル「OpenTP1 システム定義」を参照してください。

また，OpenTP1以外のRMを使う場合，トランザクションサービス定義に，set形式の定義をして，スレッドスタック領域のサイズを拡張する必要があります。

set形式の定義については，マニュアル「OpenTP1 システム定義」を参照してください。

(4)　環境変数

DBMSを使う場合，特定の環境変数が必要になる場合があります。その場合，トランザクションサービス定義，ユーザサービス定義，またはユーザサービスデフォルト定義に，putenv形式の定義をする必要があります。

putenv形式の定義については，マニュアル「OpenTP1 システム定義」を参照してください。

4.5.3　リソースマネジャ接続先選択機能

一つのリソースマネジャを複数の制御単位に分け，接続するユーザ名称などを変更してリソースマネジャに接続できます。この機能を，リソースマネジャ接続先選択機能といいます。リソースマネジャ接続先選択機能を使用すると，RPCメッセージの情報に応じてリソースマネジャの接続先を動的に変更するようにSPPを一度実装すれば，その後の業務拡大に伴ってデータベースのテーブルやサーバを追加することになっても，SPPを修正しないでデータベースの接続先を変更できます。これによって，肥大化するテスト工数や運用コストを削減できます。

この機能は，SPP，およびSUPでだけ使用できます。また，OpenTP1提供以外のリソースで使用できます。

リソースマネジャ接続先選択機能使用時にデータベースの接続先を追加する場合の例を示します。

図4‒24　リソースマネジャ接続先選択機能使用時にデータベースの接続先を追加する場合の例

クライアントがSPP3にサービス要求を送信します。

dc_trn_rm_select関数をリソースマネジャRM_XのZ3で発行し，リソースマネジャの接続先を設定します。

Z3に対して接続，更新処理を実施します。

業務量の拡大により，Z4を追加します。

SPP3に，Z4用のデータで新たなサービス要求を送信します。

dc_trn_rm_select関数をリソースマネジャRM_XのZ4で発行し，リソースマネジャの接続先を設定します。

Z4に対して接続，更新処理を実施します。

この図ではSPP1とSPP2がそれぞれZ1とZ2にだけ接続していますが，SPP3はdc_trn_rm_select関数【CBLDCTRN('RMSELECT')】を発行することで接続先を変更できるようにしています。

この機能を使用するには，トランザクションサービス定義のtrnstring定義コマンド，ユーザサービス定義およびユーザサービスデフォルト定義のtrnrmid定義コマンドを指定する必要があります。各定義コマンドについては，マニュアル「OpenTP1 システム定義」を参照してください。

(1)　dc_trn_rm_select関数の動作

リソースマネジャの接続先をUAPの処理内でプロセス，またはトランザクションごとに選択する場合は，dc_trn_rm_select関数【CBLDCTRN('RMSELECT')】を使用します。

dc_trn_rm_select関数についてはマニュアル「OpenTP1 プログラム作成リファレンス C言語編」を，CBLDCTRN('RMSELECT')についてはマニュアル「OpenTP1 プログラム作成リファレンス COBOL言語編」を参照してください。

(a)　dc_trn_rm_select関数の使用例

dc_trn_rm_select関数の使用例を次の図に示します。

図4‒25　dc_trn_rm_select関数の使用例

dc_trn_rm_select関数を使用して，接続先となるリソースマネジャ名とリソースマネジャ拡張子を設定します。

dc_trn_rm_select関数の処理の中で，接続先として指定されたリソースマネジャをオープンします。

リソースマネジャの接続先を変更するため，dc_trn_rm_select関数を再度実行します。説明1.で指定されたリソースマネジャと接続先が異なる場合は，説明1.でオープンしたリソースマネジャをクローズします。

dc_trn_rm_select関数の処理の中で，接続先として指定されたリソースマネジャをオープンします。

(b)　dc_trn_rm_select関数の発行有無による動作の違い

trnrmid定義コマンドに-kオプションを指定したリソースマネジャは，dc_trn_rm_select関数で設定するまで，トランザクションから該当するリソースマネジャに接続できません。

dc_trn_rm_select関数の発行有無による動作の違いについて，次に示します。

図4‒26　dc_trn_rm_select関数の発行有無による動作の違い

最初のdc_trn_begin関数実行時は，dc_trn_rm_select関数を発行していない状態であるため，リソースマネジャRM_XのZ1またはZ2に対するxa_open関数は発行されません。しかし，2回目のdc_trn_begin関数実行時には，dc_trn_rm_select関数で接続先が設定されたため，リソースマネジャRM_XのZ1に対するxa_open関数が発行されます。

トランザクションAはリソースマネジャRM_Xに接続できませんが，トランザクションBはリソースマネジャRM_XのZ1に接続できます。

(c)　dc_trn_rm_select関数がエラーリターンした場合の動作

dc_trn_rm_select関数がエラーになった場合は，指定したリソースマネジャは接続先として設定されません。

dc_trn_rm_select関数がエラーになった場合の動作について，次に示します。

図4‒27　dc_trn_rm_select関数がエラーになった場合の動作

2回目のdc_trn_rm_select関数がエラーリターンしたため，リソースマネジャRM_XのZ2は接続先として設定されないで，先に設定されたリソースマネジャRM_XのZ1がそのまま接続先として継続されます。

トラザクションAとBは，リソースマネジャRM_XのZ1に接続できます。

(2)　trn_rm_open_close_scopeオペランド指定時の動作

リソースマネジャのxa_open関数とxa_close関数を発行するタイミングは，トランザクションサービス定義のtrn_rm_open_close_scopeオペランドで変更できます。ただし，リソースマネジャ接続先選択機能を使用した場合，xa_open関数の発行タイミングがtrn_rm_open_close_scopeオぺランドの指定と異なることがあります。

trn_rm_open_close_scopeオペランドの指定値別に，動作について説明します。

(a)　trn_rm_open_close_scopeオペランドにprocessを指定した場合

trn_rm_open_close_scopeオペランドにprocessを指定した場合の動作を，次に示します。

図4‒28　trn_rm_open_close_scopeオペランドにprocessを指定した場合の動作

trnrmid定義コマンドに-kオプションが指定されたリソースマネジャでは，dc_rpc_open関数ではxa_open関数が発行されません。dc_trn_rm_select関数で設定されたリソースマネジャRM_XのZ1に対して，最初のdc_trn_begin関数でxa_open関数が発行されます。2回目のdc_trn_rm_select関数でリソースマネジャRM_XのZ2が設定されたため，そのタイミングでいったんリソースマネジャRM_XのZ1に対してxa_close関数を発行します。その後，dc_trn_begin関数でRM_XのZ2に対してxa_open関数が発行されます。

トランザクションAとBはリソースマネジャRM_XのZ1に接続可能で，トランザクションCはリソースマネジャRM_XのZ2に接続可能です。

(b)　trn_rm_open_close_scopeオペランドにtransactionを指定した場合

trn_rm_open_close_scopeオペランドにtransactionを指定した場合の動作を，次に示します。

図4‒29　trn_rm_open_close_scopeオペランドにtransactionを指定した場合の動作

trnrmid定義コマンドに-kオプションが指定されたリソースマネジャでは，dc_rpc_open関数ではxa_open関数が発行されません。dc_trn_rm_select関数で設定されたリソースマネジャRM_XのZ1に対して，最初のdc_trn_begin関数でxa_open関数が発行され，dc_trn_unchained_commit関数でxa_close関数が発行されます。その後，トランザクションは接続先が変更されるまで同じリソースマネジャRM_XのZ1に接続します。2回目のdc_trn_rm_select関数でリソースマネジャRM_XのZ2が設定されますが，RM_XのZ1に対するxa_close関数は前回トランザクション完了時に発行済みであるため，このタイミングでリソースマネジャRM_XのZ1に対するxa_close関数は発行されません。

トランザクションAとBはリソースマネジャRM_XのZ1に接続可能で，トランザクションＣはRM_XのZ2に接続可能です。

(3)　複数種類のリソースマネジャを指定する場合の動作

一つのトランザクションブランチから同一リソースマネジャへの接続は一つだけとなりますが，リソースマネジャが異なる場合は複数接続することができます。

複数種類のリソースマネジャを指定する場合の動作を，次に示します。

図4‒30　複数種類のリソースマネジャを指定する場合の動作

dc_trn_rm_select関数でリソースマネジャRM_XのZ1と，リソースマネジャRM_YのD1が設定されたため，最初のdc_trn_begin関数でそれぞれのリソースマネジャのxa_open関数を発行します。3回目のdc_trn_rm_select関数は，リソースマネジャRM_YのD2が指定されたためリソースマネジャRM_YのD1に対するxa_close関数を発行しますが，種別が異なるリソースマネジャであるRM_XのZ1に対するxa_close関数は発行しません。

トランザクションAはリソースマネジャRM_XのZ1とリソースマネジャRM_YのD1に接続可能で，トランザクションBはリソースマネジャRM_XのZ1とリソースマネジャRM_YのD2に接続可能です。

(4)　trnrmid定義コマンドの-kオプションの指定有無による動作の違い

trnrmid定義コマンドに-kオプションを指定しない場合，trn_rm_open_close_scopeオぺランドの指定によってプロセス開始時，またはトランザクション開始時にxa_open関数が発行されます。そのため，同一リソースマネジャについて-kオプションがあるものとないものを指定すると，-kオプション指定のリソースマネジャをdc_trn_rm_select関数で接続先として設定しても，トランザクション開始時にxa_open関数がエラーとなります。

trnrmid定義コマンドの-kオプションの指定有無による動作の違いについて，次の図に示します。

図4‒31　trnrmid定義コマンドの-kオプションの指定有無による動作の違い

trnrmid定義コマンドに-kオプションが指定されていないため，リソースマネジャRM_XのZ2に対するxa_open関数は通常どおりdc_rpc_open関数で発行します。dc_trn_rm_select関数でリソースマネジャRM_XのZ1が設定されたため，dc_trn_begin関数でxa_open関数を発行しますが，リソースマネジャRM_XのZ2に対してxa_open関数を発行済みであるため，このxa_open関数はエラーとなります。

トランザクションAは，リソースマネジャRM_XのZ2に接続できます。

リソースマネジャ接続先選択機能を使用する場合は，ユーザサービス定義に指定する同一リソースマネジャの，すべてのtrnrmid定義コマンドで-kオプションの指定を同じにしてください。

4.6　資源の排他制御

ユーザの任意の資源を，OpenTP1のUAPから排他制御する方法について説明します。任意の資源を確保する場合，OpenTP1のUAPからdc_lck_get関数【CBLDCLCK('GET ')】を呼び出します。

任意の資源の排他制御は，OpenTP1の基本機能がTP1/Server Baseの場合だけ使えます。TP1/LiNKでは，任意の資源の排他制御は使えません。

資源の排他制御は，トランザクションとして実行している処理で使います。それぞれのトランザクションから排他を指定することで，資源は正しく更新されて，UAPのトランザクション処理同士で排他できるようになります。

DAMファイルの排他制御については「4.1　DAMファイルサービス（TP1/FS/Direct Access）」を，TAMファイルの排他制御については「4.2　TAMファイルサービス（TP1/FS/Table Access）」を参照してください。

4.6.1　排他の対象となる資源

排他の対象になるのは，オペレーティングシステム内で固有の名称を定義してある，ファイルなどの資源です。ユーザ固有の資源は，ノード内で一意となる固有の名称を付けてください。排他制御する資源の名称が正しいかどうかはOpenTP1では判断できません。UAPで指定する資源名称は論理的に正しい名称を指定してください。排他指定の有効範囲は，一つのOpenTP1システム内で，かつ同じノード内に限ります。ほかのOpenTP1システム上のUAPとの排他制御はできません。

4.6.2　排他の種類

排他制御では，OpenTP1システム内で固有の資源名称と排他の条件（排他制御モード）を指定します。排他制御モードには次の2種類があります。

参照目的の排他（共用モード　PR　Protected Retrieve）

UAPは排他指定した資源の参照だけできます。ほかのUAPからの参照だけを許可します。

更新目的の排他（排他モード　EX　EXclusive）

UAPは排他指定した資源の参照，更新ができます。ほかのUAPからの参照，更新を禁止します。

排他を指定しようとした資源が，ほかのUAPですでに排他指定をされていた場合，互いの排他モードの内容によって，資源を共用できる場合とできない場合があります。

一つの資源に対して複数のUAPから排他制御の指定があった場合の，共用の可否を次の表に示します。資源を共用できない場合に，エラーリターンするか，資源の解放待ちにするかはUAPで指定できます。

表4‒13　排他制御モードの組み合わせと共用の可否

資源を確保中のUAPのモード

排他要求したUAPのモード

参照目的の排他（PR）

更新目的の排他（EX）

参照目的の排他（PR）

共用できます。

共用できません。

更新目的の排他（EX）

共用できません。

共用できません。

4.6.3　排他待ち限界経過時間の指定

UAPから排他を指定されている資源に対して，ほかのUAPが排他要求した場合，そのUAPは資源の解放を待つことができます。さらに続けて解放待ちのUAPがある場合は，ユーザサービス定義の排他待ちの優先順位の指定によって，資源の解放待ちの順番を決定して，資源の解放を待ちます。

ロックサービス定義に排他待ち限界経過時間を指定して，解放待ちのUAPが指定した時間を超えた場合は，そのUAPはエラーリターンします。

UAPが排他待ちをしている資源と排他待ち限界経過時間は，lcklsコマンドで知ることができます。

4.6.4　排他制御用のテーブルプール不足のとき

排他制御は，共用メモリのテーブルプールで管理されています。このテーブルプールが満杯のときは，dc_lck_get関数はエラーリターンします。このときはサービス関数でabort()などを呼び出して，排他の処理を取り消してください。

4.6.5　排他の解除方法

排他指定した資源を解放する方法は，次の二つの場合があります。

資源を確保しているUAPから排他を解除します。解除する資源名称を指定して排他を解除する場合は，dc_lck_release_byname関数【CBLDCLCK('RELNAME ')】を呼び出します。UAPで確保しているすべての資源を一度に解放する場合は，dc_lck_release_all関数【CBLDCLCK('RELALL ')】を呼び出します。排他を解除する関数は，その資源の排他を指定したUAPからだけ呼び出せます。排他を解除された資源は，OpenTP1が資源の解放待ちのUAPに割り当てます。

資源を確保しているUAPの同期点処理後に，そのUAPが確保していたすべての資源をOpenTP1で解放します。UAPの終了形態が正常でも異常でも，OpenTP1で自動的に解放します。

4.6.6　ロックマイグレーション

dc_lck_get関数で資源の排他をする場合，一つのグローバルトランザクション内の各トランザクションブランチに，資源の占有権が順次移動します。この機能をロックマイグレーションといいます。ロックマイグレーションによって，トランザクションブランチ間の排他待ちやデッドロックを防げます。そのため，あるグローバルトランザクションで排他を指定した資源に対しては，資源の解放をしないかぎり，一つのグローバルトランザクション内のどのトランザクションブランチからでもアクセスできます。

ロックマイグレーションは次の場合に保証されます。

一つのノード内にグローバルトランザクションがある（グローバルトランザクションが複数のノードのサービスから構成されていない）場合。

(1)　ロックマイグレーションと排他制御モード

ロックマイグレーションでは，PRモードで排他をしても，別のトランザクションブランチでEXモードと指定すれば，それ以降の排他はすべてEXモードになります。一つのグローバルトランザクション内では，一度EXモードで排他した資源には，PRモードで排他できません。すべてEXモードでの排他となります。

(2)　ロックマイグレーションでの資源の解放

ロックマイグレーションの排他は，グローバルトランザクションが終了したときに，自動的に解放されます。グローバルトランザクションの終了を待たないで，排他を解放できる場合は，次に示す方法で解放してください。

dc_lck_release_byname関数での解放

ロックマイグレーションの排他をコミット／ロールバックを待たないで解放するときは，資源名称を指定して排他を解除する関数（dc_lck_release_byname関数）を呼び出してください。排他の解除は，どのトランザクションブランチでもできます。この場合，グローバルトランザクション内でその資源に対して排他を指定した回数だけ，排他解除の関数を呼び出すまでは，資源は解放されません。

dc_lck_release_all関数での解放

全資源の排他を解除する関数（dc_lck_release_all関数）をどこかのトランザクションブランチで呼び出せば，どのトランザクションブランチで何回排他を指定していても，すべての資源が解放されます。

(3)　ロックマイグレーションでの注意事項

同期応答型RPCのdc_rpc_call関数でロックマイグレーションが起こったあとで，このdc_rpc_call関数がタイムアウトなどでエラーリターンした場合は，排他した資源に対するアクセス（確保済みの資源へのアクセスや新たな排他要求）はしないでください。アクセスした場合の動作は保証しません。

ロックマイグレーションの概要を次の図に示します。

図4‒32　ロックマイグレーションの概要

4.6.7　排他のテスト

資源の排他をする関数（dc_lck_get関数）で，資源を排他できるかどうかをテスト（flagsにDC_LCK_TESTを設定）できます。この場合dc_lck_get関数は，資源を確保できる状態でも実際に排他をしないで正常終了します。指定した資源がほかのUAPから排他されていて共用ができない場合は，排他待ちの指定の有無に関係なくDCLCKER_WAIT(00450)でエラーリターンとなります。そのほか，テストの排他の場合は次のリターン値が戻ります。デッドロックやタイムアウト，メモリ不足のエラーリターンはしません。ロックマイグレーションは起こりません。

DCLCKER_PARAM(00401)

引数の設定誤り

DCLCKER_OUTOFTRN(00455)

トランザクション処理でないUAPからの関数呼び出し

DCLCKER_VERSION(00457)

OpenTP1のライブラリとロックサービスのバージョン不一致

(1)　排他のテストをする場合の注意事項

排他のテストは，排他できる状態かどうかを知るために行います。排他のテストが正常終了したことで，それ以降の排他要求が正常終了するかどうかは保証されません。また，排他のテストが正常終了しても，実際には資源は占有されていません。そのため，排他のテストが正常終了したあとに排他を解除する関数（dc_lck_release_all関数，dc_lck_release_byname関数）を呼び出すとエラーリターンします。

4.7　デッドロックが起こったときの処置

OpenTP1のUAPでは，ほかのUAPと資源を共有して，並行に動作します。各UAPは資源の内容に矛盾が起こらないように，資源を排他制御します。ただし，複数のUAPが異なる順番で複数の資源を確保しようとすると，互いが確保している資源が解放されるのを待って処理が止まってしまうことがあります。このような状態をデッドロックといいます。

さらに，複数のUAPが異なるリソースマネジャ（RM）にアクセスすると，DAMファイルサービスの排他制御やTAMファイルサービスの排他制御が互いに影響し合って，デッドロックが起こってしまう場合もあります。ここでは，デッドロックを起こさないための注意と，デッドロックが起こった場合のOpenTP1の処置について説明します。

4.7.1　デッドロックを避けるための注意

デッドロックを避けるため，UAPからは，次のように資源へアクセスしてください。

トランザクションの終了まで資源を占有するUAPでは，できるだけ最後の処理で資源を確保します。

処理の途中で解放できる資源は，できるだけ早く解放します。

複数の資源を使用する場合は，UAP間で資源にアクセスする順番を統一しておきます。また，一つのシステム全体で資源にアクセスする順番を統一しておきます。

デッドロックが起こったときの，UAPの処理の優先順位を明確にしておきます。

4.7.2　デッドロック時のOpenTP1の処置

デッドロックが起こった場合，OpenTP1はUAPの排他待ち優先順位に従って，優先順位の低いUAPプロセスからの排他要求をエラーリターンさせます。UAPの排他待ち優先順位は，ユーザサービス定義のdeadlock_priorityオペランドに指定します。

(1)　デッドロック時のUAPの処置

デッドロックが原因で，資源を確保しようとした関数がエラーリターンした場合，UAPでは次のように対処してください。

(a)　SUP，SPPでデッドロックが起こったときの処置

SUP，またはSPPの処理でデッドロックが起こった場合は，ロールバックの関数（dc_trn_unchained_rollback関数，dc_trn_chained_rollback関数，tx_rollback関数）でトランザクションをロールバックさせてください。デッドロックでロールバックしたSUP，またはSPPは再実行（リトライ）しません。もう一度該当するサービスをクライアントUAPから要求し直してください。

(b)　MHPでデッドロックが起こったときの処置

MHPの処理でデッドロックが起こった場合は，dc_mcf_rollback関数でロールバックしてください。再実行（リトライ）するかどうかは，dc_mcf_rollback関数の引数に指定します。

(2)　デッドロック情報，タイムアウト情報の出力

デッドロックが起こった場合，デッドロックの原因となったUAPの詳細情報を，ロックサービスがあるノードのディレクトリに出力できます。この情報をデッドロック情報といいます。

資源の解放を待っているUAPが，ロックサービス定義のlck_wait_timeoutオペランドに指定した時間を超えた場合，UAPで呼び出した関数はエラーリターンします。このとき，確保しようとした資源に関する詳細情報を，ロックサービスがあるノードのディレクトリに出力できます。この情報をタイムアウト情報といいます。

デッドロック情報，タイムアウト情報を出力するかどうかは，ロックサービス定義のlck_deadlock_infoオペランドに指定します。

デッドロック情報，タイムアウト情報の出力形式については，「付録B　デッドロック情報の出力形式」を参照してください。

(a)　デッドロック情報，タイムアウト情報の削除

デッドロック情報，タイムアウト情報を削除する方法を次に示します。

コマンドで削除する方法

lckrminfコマンドを実行します。

OpenTP1の開始時に，前回までのオンラインで作成した情報を削除する方法

ロックサービス定義のlck_deadlock_info_removeオペランドとlck_deadlock_info_remove_levelオペランドに，削除する条件を指定しておきます。

(3)　複数のリソースマネジャでデッドロックが起こった場合のOpenTP1の処置

複数のリソースマネジャにアクセスするUAP同士でデッドロックが起こった場合の，OpenTP1の処置を示します。

(a)　OpenTP1で排他制御するRM（DAM，TAM）同士のデッドロックの場合

ユーザサービス定義のdeadlock_priorityオペランドに指定した，UAPの排他待ち優先順位の値に従って，処置します。

(b)　OpenTP1で排他制御するRM（DAM，TAM）と 他社RMとのデッドロックの場合

ロックサービス定義のlck_wait_timeoutオペランドに指定した排他待ち限界経過時間で監視します。RM固有に指定した限界経過時間は参照しないので，ロックサービス定義の排他待ち限界経過時間は必ず指定しておいてください。

(c)　他社RMと他社RMとのデッドロックの場合

RM固有に指定した限界経過時間も，ロックサービス定義の排他待ち限界経過時間も参照しません。この場合，OpenTP1はトランザクションの限界経過時間でUAPを監視します。ユーザサービス定義，ユーザサービスデフォルト定義，トランザクションサービス定義のtrn_expiration_timeオペランドに指定した値を超えた場合に，該当するUAPのプロセスを異常終了させます。

5　X/Openに準拠したアプリケーションプログラミングインタフェース

X/Openに準拠したアプリケーションプログラミングインタフェース（XATMIインタフェース，TXインタフェース）をOpenTP1のアプリケーションプログラムで使う場合の機能について説明します。

この章では，各機能をC言語の関数名で説明します。C言語の関数名に該当するCOBOL言語のAPIは，関数を最初に説明する個所に【 】で囲んで表記します。それ以降は，C言語の関数名に統一して説明します。COBOL言語のAPIがない関数の場合は，【 】の表記はしません。

5.1　XATMIインタフェース（クライアント／サーバ形態の通信）

XATMIインタフェースとは，オープンシステムの標準化団体であるX/Openで規定するDTPモデルに準拠した，クライアント／サーバ形態の通信をするためのAPIです。OpenTP1では，XATMIインタフェースを使って，UAPプロセス間の通信ができます。

OpenTP1のUAP種別とXATMIインタフェースの関係

XATMIインタフェースの通信を使えるのは，SUP，SPPです。MHPではXATMIインタフェースの関数は使えません。また，SUP，SPPの両方に，XATMIインタフェース定義ファイルから作成したスタブを結合しておいてください。

UAPプロセスの実行環境や開始，または終了方法など，OpenTP1のUAP操作に関しては，特に記述しないかぎり，OpenTP1のRPC（dc_rpc_call関数）を使ったクライアント／サーバ形態の通信と同様です。

5.1.1　XATMIインタフェースでできる通信形態

XATMIインタフェースでできる通信形態について説明します。

XATMIインタフェースの通信は，通信プロトコルにTCP/IPを使います。また，通信プロトコルにOSI TPを使っている場合にも，XATMIインタフェースを使えます。通信プロトコルとXATMIインタフェースの機能の関係については，「5.1.2　XATMIインタフェースの機能」を参照してください。

OSI TP通信をする場合は，OpenTP1システムにTP1/NET/OSI-TP-Extendedが必要です。TP1/NET/OSI-TP-Extendedのセットアップ手順については，マニュアル「OpenTP1 プロトコル TP1/NET/OSI-TP-Extended編」を参照してください。

(1)　通信の形態

XATMIインタフェースでは，次に示す通信形態を提供します。

リクエスト／レスポンス型サービスの通信

サービス関数に一つの要求を送信して，一つの応答を受信する通信です。OpenTP1のリモートプロシジャコールと同様の，サービスを要求して結果を受信する通信です。

会話型サービスの通信

通信相手のサービス関数を起動して確立したコネクションを介して，サービス関数と互いにデータを送受信する通信です。

会話型サービスの通信ができるのは，通信プロトコルにTCP/IPを使っている場合だけです。通信プロトコルにOSI TPを使っている場合は，会話型サービスの通信はできません。

(2)　サービスの要求方法

サービスを要求するときは，サーバUAPのサービス関数を識別する名称（サービス名）を引数に設定した関数を呼び出します。

(3)　XATMIインタフェースの通信で使うデータ

XATMIインタフェースの通信では，C言語の場合は構造体，COBOL言語の場合はレコードを送受信のデータに使えます。そのため，1回のサービス要求でまとまったデータを送信できます。このデータをC言語の場合は型付きバッファ（タイプトバッファ），COBOL言語の場合は型付きレコード（タイプトレコード）といいます。通信で使う型付きのデータについては，「5.1.6　通信データの型」を参照してください。

5.1.2　XATMIインタフェースの機能

XATMIインタフェースのアプリケーションプログラミングインタフェースと通信プロトコル別で使える機能について説明します。

(1)　XATMIインタフェースのライブラリ関数

XATMIインタフェースのライブラリ関数の一覧を次の表に示します。

表5‒1　XATMIインタフェースのライブラリ関数の一覧

XATMIインタフェースの機能

ライブラリ関数名

C言語ライブラリ

COBOL言語ライブラリ

リクエスト／レスポンス型サービスの通信

リクエスト／レスポンス型サービスの呼び出しと応答の受信

tpcall()

TPCALL

リクエスト／レスポンス型サービスの呼び出し

tpacall()

TPACALL

リクエスト／レスポンス型サービスからの非同期応答の受信

tpgetrply()

TPGETRPLY

リクエスト／レスポンス型サービスのキャンセル

tpcancel()

TPCANCEL

会話型サービスの

通信

会話型サービスとのコネクションの確立

tpconnect()

TPCONNECT

会話型サービスとのコネクションの切断

tpdiscon()

TPDISCON

会話型サービスからのメッセージの受信

tprecv()

TPRECV

会話型サービスへのメッセージの送信

tpsend()

TPSEND

通信データの型の操作

型付きバッファの割り当て

tpalloc()

−

型付きバッファの解放

tpfree()

−

型付きバッファのサイズの変更

tprealloc()

−

型付きバッファの情報の取得

tptypes()

−

サービス名を動的に管理

サービス名の広告

tpadvertise()

TPADVERTISE

サービス名の広告の取り消し

tpunadvertise()

TPUNADVERTISE

サーバで使う関数

サービス関数のテンプレート※

tpservice()

−

サービスルーチンの開始※

−

TPSVCSTART

サービス関数からのリターン

tpreturn()

TPRETURN

（凡例）

−：該当するAPIがないことを示します。

注※

C言語とCOBOL言語ではサービス開始を宣言する方法が異なるため，別のAPIとしています。tpservice()は，C言語のサービスの実体を示します。

XATMIインタフェースの関数とOpenTP1のUAPの関係を次の表に示します。

表5‒2　XATMIインタフェースの関数とOpenTP1のUAPの関係

XATMIインタフェースの関数

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

tpacall()

○

○

○

○

○

−

−

−

tpadvertise()

−

−

○※1

○※1

○※1

−

−

−

tpalloc()

○

○

○

○

○

−

−

−

tpcall()

○

○

○

○

○

−

−

−

tpcancel()

○

○

○

○

○

−

−

−

tpconnect()

○

○

○

○

○

−

−

−

tpdiscon()

○

○

○

○

○

−

−

−

tpgetrply()

○

○

○

○

○

−

−

−

tpfree()

○

○

○

○

○

−

−

−

tprecv()

○

○

○

○

○

−

−

−

tprealloc()

○

○

○

○

○

−

−

−

tpreturn()

−

−

○※2

○※2

○※2

−

−

−

tpsend()

○

○

○

○

○

−

−

−

tpservice()※3

−

−

−

−

−

−

−

−

tptypes()

○

○

○

○

○

−

−

−

tpunadvertise()

−

−

○※1

○※1

○※1

−

−

−

（凡例）

○：関数を呼び出せます。

−：関数を呼び出せません。

注

MHPの「トランザクション処理の範囲でない」とは，非トランザクション属性のMHP，またはMHPのメイン関数の範囲を示します。

注※1

サービス関数の中でだけ，呼び出せます。

注※2

XATMIインタフェースのサービス関数をリターンするためだけに使います。

注※3

tpservice()は，サービス関数の実体です。

(2)　XATMIインタフェースの機能と通信プロトコルの関係

XATMIインタフェースの通信は，TCP/IP通信でもOSI TP通信でも使えます。ただし，通信プロトコルによって制限がある機能もあります。XATMIインタフェースの機能と通信プロトコルの関係を次の表に示します。

表5‒3　XATMIインタフェースの機能と通信プロトコルの関係

XATMIインタフェースの機能

通信プロトコル

TCP/IP

OSI TP

リクエスト／レスポンス型の通信

○

○

会話型サービスの通信

○

−

型付きのデータ送信

○

○※

OpenTP1同士のクライアント／サーバ型通信

○

○

他TPモニタへのトランザクション拡張

−

○

（凡例）

○：該当する通信プロトコルで使えます。

−：該当する通信プロトコルでは使えません。

注※

OSI TPを使ってOpenTP1以外のシステムとクライアント／サーバ形態で通信する場合でも，通信データの型を変換して送信できます。指定する通信データの型については，「5.1.6　通信データの型」を参照してください。

5.1.3　リクエスト／レスポンス型サービスの通信

XATMIインタフェースの，リクエスト／レスポンス型サービスの通信形態について説明します。

(1)　リクエスト／レスポンス型サービスの種類

リクエスト／レスポンス型サービスの通信形態の種類を次に示します。

(a)　同期的に応答を受信する通信

サービスを要求してから，応答が返ってくるのを待つ通信です。サービスの要求には，関数tpcall()【TPCALL】を使います。

（監視時間について）

同期的に応答を受信する通信では，応答が返るまでの待ち時間を監視します。最大応答待ち時間は，OpenTP1の定義で指定します。定義については，マニュアル「OpenTP1 システム定義」を参照してください。

tpcall()を呼び出したプロセスがトランザクション下にある場合，最大応答待ち時間は，定義のtrn_expiration_timeオペランドで指定した値となります。この場合，最大応答待ち時間を過ぎると，そのプロセスは異常終了します（tpcall()はエラーリターンしません）。

tpcall()を呼び出したプロセスがトランザクション下にない場合，最大応答待ち時間は，定義のwatch_timeオペランドで指定した値となります。この場合，最大応答待ち時間を過ぎると，tpcall()はエラーリターンします。

同期的に応答を受信するリクエスト／レスポンス型サービスの通信形態を次の図に示します。

図5‒1　同期的に応答を受信するリクエスト／レスポンス型サービスの通信形態

(b)　非同期に応答を受信する通信

サービスを要求してから，応答が返ってくるのを待たないで，処理を続ける通信です。その後，応答を受信する関数を使って，応答を受信します。サービスの要求には，関数tpacall()【TPCALL】を使います。そして，応答を受信するための関数tpgetrply()【TPGETRPLY】を使います。

（監視時間について）

非同期に応答を受信する通信では，tpgetrply()で応答を受信するまで待ちます。最大応答待ち時間は，OpenTP1の定義で指定します。定義については，マニュアル「OpenTP1 システム定義」を参照してください。

tpacall()，またはtpgetrply()を呼び出したプロセスがトランザクション下にある場合，最大応答待ち時間は，定義のtrn_expiration_timeオペランドで指定した値となります。この場合，最大応答待ち時間を過ぎると，そのプロセスは異常終了します（tpgetrply()はエラーリターンしません）。

tpacall()，またはtpgetrply()を呼び出したプロセスがトランザクション下にない場合，最大応答待ち時間は，定義のwatch_timeオペランドで指定した値となります。この場合，最大応答待ち時間を過ぎると，tpgetrply()はエラーリターンします。

非同期に応答を受信するリクエスト／レスポンス型サービスの通信形態を次の図に示します。

図5‒2　非同期に応答を受信するリクエスト／レスポンス型サービスの通信形態

(c)　応答を返さない通信

サービス要求の処理結果が戻らない通信です。応答を返さない通信では，関数tpacall()のフラグにTPNOREPLYを設定して使います。ただし，tpacall()のフラグにTPNOTRANも合わせて設定する必要があります。

非応答型の通信でサービス要求をした場合，応答は受信できません。サービスを要求したUAPは，処理を続けます。

応答を返さないリクエスト／レスポンス型サービスの通信形態を次の図に示します。

図5‒3　応答を返さないリクエスト／レスポンス型サービスの通信形態

(2)　リクエスト／レスポンス型サービスの通信の時間監視

リクエスト／レスポンス型サービスの通信では，時間監視はすべてOpenTP1の定義に指定した値に従います。定義については，マニュアル「OpenTP1 システム定義」を参照してください。

タイムアウトには，トランザクション処理がタイムアウトになったことを示すトランザクションタイムアウトと，ブロッキング状態の待ちによるタイムアウトによるブロッキングタイムアウトがあります。トランザクションタイムアウトが起こった場合，そのプロセスは異常終了します。

設定したタイムアウト値を超えて，処理を待つ場合もあります（該当のデータでない応答が返ってきても，OpenTP1の監視タイマはリセットされるため）。また，フラグにTPNOTIMEを設定した場合は，タイムアウト値を無限大とします。ただし，トランザクションタイムアウトはこのフラグの有無に関係なく起こります。

(3)　リクエスト／レスポンス型サービスの通信とトランザクションの関係

OpenTP1で使えるトランザクション管理の関数（dc_trn_〜，またはtx_〜）でトランザクションを制御します。OpenTP1でのトランザクション決着，またはrollback_only状態かどうかは，サービス関数の処理結果，またはトランザクションを制御する関数によって決定されます。ただし，リクエスト／レスポンス型サービスでは，次に示すエラーが起こると，該当のトランザクションブランチをrollback_only状態とします。

トランザクションタイムアウトが発生（プロセスは異常終了します）。

型付きバッファ受信のエラー（受信した型が，許可されていない）。

TPESVCERR，TPESVCFAILエラーの発生（tpreturn()のエラー通知，または，tpreturn()を使ったユーザからのエラー通知）。

TPESYSTEMエラーの発生（ただし，TPESYSTEMがリターンしてもrollback_only状態とならない場合もあります）。

(a)　同期的に応答を受信する通信のトランザクション管理

呼び出し側がトランザクション下にある場合，呼び出すサービスをトランザクションとして処理するかどうかは，関数tpcall()の引数flagsに設定したパラメタで決まります。呼び出すサービスをトランザクションとしない場合に限り，TPNOTRANを設定してください。TPNOTRANを設定しても，トランザクションタイムアウトは起こります。

(b)　非同期的に応答を受信する通信のトランザクション管理

呼び出し側がトランザクション下にある場合，呼び出すサービスをトランザクションとして処理するかどうかは，関数tpacall()の引数flagsに設定したパラメタで決まります。呼び出すサービスをトランザクションとしない場合に限り，TPNOTRANを設定してください。TPNOTRANを設定しても，トランザクションタイムアウトは起こります。

(c)　応答を返さない通信のトランザクション管理

応答を返さない通信はトランザクションとして処理できません。関数tpacall()の引数flagsにTPNOTRANを必ず設定してください。

(4)　ブロッキング状態が発生した場合の処置

リクエスト／レスポンス型サービスの通信関数には，ブロッキング状態の場合の処置を示すTPNOBLOCKフラグがあります。このフラグを設定したtpgetrply()は，ブロッキング状態を検知した時点でエラーリターンします。このフラグを設定しないと，ブロッキング状態が解決するまで待つか，またはタイムアウトとなります（ただし，TPNOTIMEを設定していれば，ブロッキング状態が原因でのタイムアウトとはなりません）。OpenTP1では，このフラグが有効になるのは，tpgetrply()だけです。tpcall()，tpacall()でこのフラグを設定しても無効となります。

5.1.4　会話型サービスの通信

XATMIインタフェースの，会話型サービスの通信形態について説明します。

会話型サービスの通信ができるのは，通信プロトコルにTCP/IPを使っている場合だけです。通信プロトコルにOSI TPを使っている場合は，会話型サービスの通信はできません。

(1)　会話型サービスの通信手順

会話型サービスの通信形態では，関数を呼び出して，通信相手とコネクションを確立してから通信をします。サービスを要求する手順を次に示します。

(a)　コネクションの確立

クライアントUAPは，サービス関数とのコネクションを確立します。コネクションを確立するときは，tpconnect()【TPCONNECT】を使います。tpconnect()でコネクションを確立したUAPプロセスをオリジネータ，相手のUAPプロセスをサブオーディネータといいます。

tpconnect()が正常リターンした場合には，確立したコネクションを識別する記述子が正の値で返されます。この記述子を通信する関数に設定して，通信します。

サービス関数でtpreturn()を呼び出して処理を終了すると，コネクションは切断されます。

（コネクションの制御権）

tpconnect()の引数flagsには，制御権の有無を示すTPSENDONLY，TPRECVONLYのどちらかを設定します。TPSENDONLYを設定することで，そのプロセスは制御権を得て，データの送信関数tpsend()を使えるようになります。逆に，TPRECVONLYを設定すると，通信相手のプロセスに制御権が渡って，tpconnect()を呼び出したプロセスはデータの受信関数tprecv()を使えるようになります。

(b)　データの送信（tpsend()）

データを送信するときは，tpsend()【TPSEND】を使います。tpsend()の引数には，tpconnect()でリターンされた記述子を設定して，使うコネクションを特定します。

コネクションの制御権がない場合には，tpsend()は使えません。この場合，tpsend()はエラーリターンします。

コネクションの制御権を通信相手のプロセスに渡したい場合は，tpsend()のflagsにTPRECVONLYを設定します。このフラグを設定してtpsend()を呼び出すことで，通信相手のプロセスに制御権を渡すことになります。

サブオーディネータからtpsend()でデータを送信する場合は，受信したTPSVCINFO構造体から得た記述子を使ってください。

(c)　データの受信（tprecv()）

データを受信するときは，tprecv()【TPRECV】を使います。データは，非同期に受信します。tprecv()は，コネクションの制御権を持たないプロセスからだけ呼び出せます。

（監視時間について）

フラグにTPNOBLOCKを設定していない場合，tprecv()はデータを受信するまで待ちます。最大応答待ち時間は，OpenTP1の定義で指定します。定義については，マニュアル「OpenTP1 システム定義」を参照してください。

tprecv()を呼び出したプロセスがトランザクション下にある場合，最大応答待ち時間は，OpenTP1のシステム定義trn_expiration_timeオペランドで指定した値となります。この場合，最大応答待ち時間を過ぎると，そのプロセスは異常終了します（tprecv()はエラーリターンしません）。

tprecv()を呼び出したプロセスがトランザクション下にない場合，最大応答待ち時間は，OpenTP1のシステム定義watch_timeオペランドで指定した値となります。この場合，最大応答待ち時間を過ぎると，tprecv()はエラーリターンします。

(d)　コネクションの切断

サービス関数の処理が終了して，tpreturn()【TPRETURN】を呼び出すと，コネクションは正常に切断されます。また，通信中にエラーが起こったことで，コネクションが切断される場合もあります。

(e)　コネクションの強制切断

何らかの理由でコネクションを強制的に切断する場合は，tpdiscon()【TPDISCON】を使います。tpdiscon()に設定した記述子は，以降の処理では無効になります。また，トランザクションの処理の場合は，サブオーディネータ側のトランザクションブランチはrollback_only状態になります。

会話型サービスの通信形態を次の図に示します。

図5‒4　会話型サービスの通信形態

(2)　会話型サービス通信の時間監視

会話型サービスの通信では，時間監視はすべてOpenTP1の定義に指定した値に従います。定義については，マニュアル「OpenTP1 システム定義」を参照してください。

タイムアウトには，トランザクション処理がタイムアウトになったことを示すトランザクションタイムアウトと，ブロッキング状態の待ちによるタイムアウトによるブロッキングタイムアウトがあります。トランザクションタイムアウトが起こった場合，そのプロセスは異常終了します。

設定したタイムアウト値を超えて，処理を待つ場合もあります（該当のデータでない応答が返ってきても，OpenTP1の監視タイマはリセットされるため）。また，フラグにTPNOTIMEを設定した場合は，タイムアウト値を無限大とします。ただし，トランザクションタイムアウトはこのフラグの有無に関係なく起こります。

(3)　会話型サービスの通信とトランザクションの関係

OpenTP1で使えるトランザクション管理の関数（dc_trn_〜，またはtx_〜）でトランザクションを制御します。OpenTP1でトランザクションを決着するかどうか，またはrollback_only状態かどうかは，サービス関数の処理結果，またはトランザクションを制御する関数によって決定されます。ただし，会話型サービスでは，次に示すエラーが起こると，該当のトランザクションブランチをrollback_only状態とします。

トランザクションタイムアウトが発生（異常終了します）。

型付きバッファ受信のエラー（受信した型が，許可されていない）。

TPESYSTEMエラーの発生（ただし，TPESYSTEMがリターンしてもrollback_only状態とならない場合もあります）。

tpdiscon()を実行。

tpsend()でエラーコードTPEEVENT（イベントコードがTPEV_SVCERR，TPEV_SVCFAIL）。

tprecv()でエラーコードTPEEVENT（イベントコードがTPEV_DISCONIMM，TPEV_SVCERR，TPEV_SVCFAIL）。

呼び出し側がトランザクション下にある場合，呼び出すサービスをトランザクションとして処理するかどうかは，関数tpconnect()の引数flagsに設定したパラメタで決まります。呼び出すサービスをトランザクションとしない場合に限り，TPNOTRANを設定してください。TPNOTRANを設定しても，トランザクションタイムアウトは起こります。

(4)　ブロッキング状態が起こった場合の処置

会話型サービスの通信関数には，ブロッキング状態の場合の処置を示すTPNOBLOCKフラグがあります。このフラグを設定したtprecv()は，ブロッキング状態を検知した時点でエラーリターンします。このフラグを設定しないと，ブロッキング状態が解決するまで待つか，またはタイムアウトとなります（ただし，TPNOTIMEを設定していれば，ブロッキング状態が原因でのタイムアウトとはなりません）。OpenTP1では，このフラグが有効になるのは，tprecv()だけです。tpconnect()，tpsend()でこのフラグを設定しても無効となります。

(5)　イベントの受信

コネクションを識別する記述子cdにイベントが存在した場合，会話型サービスの通信関数（tpsend()，tprecv()）でそのイベントを受信できます。イベントは，通信に関する情報を示します。詳細については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

5.1.5　OpenTP1での注意事項

OpenTP1でXATMIインタフェースを使って通信する場合は，次の点に注意してください。

XATMIインタフェースを使うユーザサーバのユーザサービス定義には，次の値を必ず指定してください。

server_type = "xatmi"

XATMIインタフェースでは，サービスグループの概念はありません。ただし，OpenTP1でXATMIインタフェースを使った通信をする場合は，UAPのユーザサービス定義にサービスグループを設定してください。

XATMIインタフェースを使う場合は，ユーザサービス定義，またはユーザサービスデフォルト定義に次の値を必ず指定してください。

trn_expiration_time = 0以外の値
trn_expiration_time_suspend = Y

tpcall()，tpacall()，tpconnect()，tpsend()でデータを送信するときにブロッキング状態が起こって，一定時間が経ってもブロッキング状態が解除されなかった場合，TPENOBLOCKフラグの有無に関係なく，TPESYSTEMがリターンされます。TPESYSTEMでエラーリターンするまでの時間は，定義のサービス要求送信リトライ回数，間隔によって決まります。

トランザクションタイムアウトが起こったときは，TPETIMEはリターンされないで，そのプロセスは異常終了します。

dc_rpc_call関数で呼ばれて，XATMIインタフェースの関数（tpcall()など）を呼び出すUAPには，RPCインタフェース定義とXATMIインタフェース定義のクライアント用定義の両方を指定して作成したスタブをリンケージしておいてください。この場合のスタブを作成する方法については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

tx_commit()などでトランザクションを決着させた場合には，それ以前のすべての未受信データは無効となります。

ノード間負荷バランス機能およびノード間負荷バランス拡張機能を使う場合，dc_rpc_call関数の場合と同様に，複数用意したSPPのサービスグループ名をユーザサービス定義で一致させる必要があります。その際には，ユーザサービス定義でサービス名と実行形式ファイル名を一致させてください。サービス名が一致していない場合は，tpcall()，tpacall()，tpconnect()が失敗する場合があります。実行形式ファイル名が一致していない場合は，どのサーバUAPがスケジュールされたかによって処理結果がまちまちになります。

OSI-TP通信を使用したトランザクションブランチは，相手システムとのアソシエーションがなければ回復できません。また，相手システムに対する着呼のアソシエーションだけでは回復できない場合があります。必ず発呼のアソシエーションを定義してください。トランザクションブランチの回復ができない場合は，相手システムとのアソシエーションが確立されているかどうか確認してください。ただし，同じ相手システムに対する複数のトランザクションブランチの回復が並列に実行されないで時間が掛かる場合があります。

XATMIインタフェースAPIで送受信できる最大データ長は500キロバイトです。

5.1.6　通信データの型

XATMIインタフェースの通信では，1回のサービス要求でまとまったデータを送信できるように，C言語の場合は構造体，COBOL言語の場合はレコードを送受信のデータに使えます。このデータを，C言語の場合は型付きバッファ（タイプトバッファ），COBOL言語の場合は型付きレコード（タイプトレコード）といいます。

(1)　通信データの型の構成

通信データの型は，タイプ（type）とサブタイプ（subtype）から構成されます。UAPで使う通信データの型は，UAPを作成するときにスタブのソースファイル（XATMIインタフェース定義）で指定します。XATMIインタフェース定義については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

(a)　タイプ（type）

XATMIインタフェースで規定するデータ型の呼称です。それぞれのタイプには次の特長があります。

X_OCTET

オクテットの配列（バイト列）から成るデータ型です。X_OCTETには，サブタイプはありません。

X_COMMON

入れ子にならない構造体またはレコードのことです。サブタイプで構造を特定します。

X_C_TYPE

入れ子にならない構造体またはレコードのことです。サブタイプで構造を特定します。

(b)　サブタイプ（subtype）

それぞれのタイプで使える範囲のデータを要素に持つ，構造体またはレコードを示す名称です。

タイプで使えるデータ型については，「5.1.6(3)　タイプで使えるデータ型の一覧」を参照してください。

(2)　通信データの型の使い方

型付きバッファまたは型付きレコードを使うと，C言語の場合は構造体で，COBOL言語の場合はレコードでデータをやり取りできます。また，関数のフラグの設定によって，設定した受信用のデータ型と異なるタイプやサブタイプ，異なる大きさのデータでも受信できます。ただし，UAPで扱える通信データの型は，UAPにXATMIインタフェース定義で事前に定義した値と一致していることが前提です。

(3)　タイプで使えるデータ型の一覧

型付きバッファを使うときは，XATMIインタフェース定義（サーバUAP用）にタイプ，サブタイプ，およびデータ型を指定します。XATMIインタフェース定義ファイルからスタブを生成して，スタブのオブジェクトファイルをサーバUAPにリンケージすると，該当する型付きバッファを使えるようになります。XATMIインタフェース定義については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編を参照してください。

通信プロトコルにOSI TPを使ってOpenTP1以外のシステムと通信する場合でも，通信相手システムで型付きバッファおよび型付きレコードを認識できるように変換して送信できます。

タイプで使えるデータ型の一覧を次の表に示します。識別子とはXATMIインタフェース定義に記述するデータ型を示し，C言語のデータ型およびCOBOL言語のデータとは実際にスタブに定義される型付きバッファおよび型付きレコードを示します。OpenTP1以外のシステムと通信するためにデータ型を変換する場合は，変換する識別子をXATMIインタフェース定義に指定します。

表5‒4　タイプで使えるデータ型の一覧

タイプ

識別子

C言語のデータ型

COBOL言語の

データ型

通信プロトコル

備考

TCP/IP

OSI TP

X_OCTET

−※1

−※1

−※1

○

○

なし

X_COMMON

short a

short a

PIC S9(4) COMP-5

○

○

なし

short a[n]

short a[n]

PIC S9(4) COMP-5

OCCURS n TIMES

○

○

なし

long a

DCLONG a

PIC S9(9) COMP-5

○

○

なし

long a[n]

DCLONG a[n]

PIC S9(9) COMP-5

OCCURS n TIMES

○

○

なし

char a※2

char a

PIC X

○

○

無変換配列

octet a

char a

PIC X

○

○

無変換配列

tchar a

char a

PIC X

−

○

変換配列

char a[n]※2

char a[n]

PIC X(n)

○

○

無変換配列

octet a[n]

char a[n]

PIC X(n)

○

○

無変換配列

tchar a[n]

char a[n]

PIC X(n)

−

○

変換配列

X_C_TYPE

short a

short a

−

○

×

なし

short a[n]

short a[n]

−

○

×

なし

long a

DCLONG a

−

○

×

なし

long a[n]

DCLONG a[n]

−

○

×

なし

int4 a

DCLONG a

−

○

×

なし

int4 a[n]

DCLONG a[n]

−

○

×

なし

char a ※2

char a

−

○

×

なし

octet a

char a

−

○

×

なし

tchar a

char a

−

○

×

なし

char a[n]※2

char a[n]

−

○

×

なし

octet a[n]

char a[n]

−

○

×

なし

tchar a[n]

char a[n]

−

○

×

なし

float a

float a

−

○

×

なし

float a[n]

float a[n]

−

○

×

なし

double a

double a

−

○

×

なし

double a[n]

double a[n]

−

○

×

なし

octet a[n][n]

char a[n][n]

−

○

×

なし

tchar a[n][n]

char a[n][n]

−

○

×

なし

str a[n]

char a[n]

−

○

×

なし

str a[n][n]

char a[n][n]

−

○

×

なし

tstr a[n]

char a[n]

−

○

×

なし

tstr a[n][n]

char a[n][n]

−

○

×

なし

（凡例）

○：該当する通信プロトコルで使えます。

×：該当する通信プロトコルでは使えません。

−：変換の識別子でも，無変換としてそのまま処理されます。

注※1

X_OCTETは，定義しなくても自動的に認識されます。XATMIインタフェース定義にX_OCTETを指定した場合は，スタブを生成するコマンドを実行したときにエラーになります。

注※2

この識別子も使えますが，新規で作成する場合は次に示す識別子を使うことをお勧めします。

X_COMMONの場合：octetまたはtchar

X_C_TYPEの場合：strまたはtstr

(4)　型付きバッファを操作する関数の使い方

XATMIインタフェースの関数で通信データを操作する方法について説明します。通信データを操作できるAPIは，C言語でだけ使えます。COBOL言語の場合は，通信データを操作するためのAPIはありません。

(a)　型付きバッファの確保

型付きバッファを確保する場合は，タイプとサブタイプの値を設定したtpalloc()をUAPから呼び出します。tpalloc()で確保した領域は，NULLでクリアされます。

(b)　型付きバッファの再確保

型付きバッファの長さを大きくする場合は，tprealloc()を使います。tprealloc()で使えるバッファ型は，X_OCTETだけです。それ以外のバッファ型を指定した場合は，エラーリターンします。変更後のバッファ長が短い場合は，バッファに入り切らない分は切り捨てられます。逆に，変更後のバッファ長が長い場合は，余った部分がNULLクリアされます。

再確保に失敗すると，変更前のバッファ型も無効になります。

(c)　型付きバッファの解放

確保した領域を解放する場合は，tpfree()を使います。引数には型付きバッファへのポインタを設定します。型付きバッファのポインタでない値を設定した場合は，無視されます。

(d)　型付きバッファの情報の取得

バッファのタイプなどの情報を取得する場合は，tptypes()を使います。

(e)　型付きバッファを操作する場合の注意事項

型付きバッファを操作する関数は，Cライブラリのmalloc()，realloc()，free()と一緒には使わないでください（例えば，tpalloc()で割り当てたバッファは，free()で解放しないでください）。確保した型付きバッファに対して，free()を呼び出した場合の動作は保証しません。

(5)　X_OCTET型を使用する場合の注意

X_OCTET型の型付きバッファを使う場合は，ほかの型のバッファを使う場合と次に示す点で異なります。

subtype（構造体）を持たない（subtypeごとに必要な情報がない）。

データを変換しないで送信する（単なるビット配列として，データを扱う）。

長さを示すパラメタを指定する必要がある。

5.1.7　サーバUAPの作成方法

XATMIインタフェースの通信で使うサービス関数（サーバUAP）から関数を呼び出す方法について説明します。OpenTP1のサービス関数とは，コーディングの方法が異なります。

(1)　サーバUAPで提供するサービス関数のコーディング

C言語の場合は，サービス関数のコーディングをするときは，tpservice()で示す形式に従ってください。tpservice()では，コーディングするための標準的な形式を示します。

COBOL言語の場合は，サービスプログラムの処理でXATMIインタフェースのAPIを使う前にTPSVCSTARTを呼び出します。

(a)　サービス関数の終了方法

サービス関数は，tpreturn()【TPRETURN】を呼び出すことでその処理が終了したことになります。XATMIインタフェースの通信では，returnでサービス関数を終了する直前に，必ずtpreturn()を呼び出してください。tpreturn()を呼び出したあとで何らかの処理をした場合，その動作については保証しません。

(b)　サービス名の広告

サーバUAPでは，自分のサービス名がサービスを提供できる状態であることを宣言できます（サービス名の広告）。サービス名を広告する場合は，tpadvertise()【TPADVERTISE】を使います。

サーバUAPの起動時には，ユーザサービス定義に指定してあるサービスが広告済みとなります。ユーザサービス定義に指定してあるサービス名でtpadvertise()を呼び出す必要はありません。

サービス名の広告を取り消す場合は，tpunadvertise()【TPUNADVERTISE】を使います。tpunadvertise()を呼び出すことで，該当のサービス名に対するサービス要求はエラーリターンします。いったんtpunadvertise()で広告を取り消したサービス名でも，そのあとでtpadvertise()を呼び出せば，再びサービス要求を受け付けることができます。

tpadvertise()とtpunadvertise()は，SPPでだけ使えます。ただし，dc_rpc_mainloop関数を呼び出す前には使えません。

tpadvertise()は，広告する関数アドレスを引数に持っていて，広告できるかどうかをチェックします。OpenTP1では，tpadvertise()を呼び出すサーバへのサービスグループと，サービスを広告しているサーバのサービスグループが同じであれぱ，すでに広告されていると見なして正常リターンします。サービスグループが一致しないと，tpadvertise()はエラーリターンします。

(2)　一つのノードでの負荷分散（マルチサーバ負荷バランス）と，tpunadvertise()の関係

一つのノードで負荷分散している場合（マルチサーバ負荷バランス機能を使用している場合），tpunadvertise()をどれか一つのプロセスから呼び出すと，負荷分散しているプロセスすべてでサービスを受け付けられなくなります。その後，tpadvertise()で再びサービスを広告すれば，サービス要求を受け付けられるようになります。

マルチサーバを使えるのは，キュー受信型サーバ（スケジュールサービスでスケジュールされるSPP）です。ソケット受信型サーバはマルチサーバを使えません。

5.1.8　OpenTP1の機能とXATMIインタフェースの関係

(1)　UAPトレース

XATMIインタフェースの通信を使った場合にも，UAPトレースは取得します。UAPトレースについては，マニュアル「OpenTP1 テスタ・UAPトレース 使用の手引」を参照してください。

(2)　統計情報

システム稼働統計情報の取得は，RPCの情報に追加されます。ただし，該当バージョンのOpenTP1では，一部の障害情報は取得されません（XATMI独自の障害や，ユーザサーバの実行時間など）。特に，会話型サービスの形態はXATMIインタフェースの通信独自の通信方法なので，tpsend()とtprecv()などの障害の統計情報は取得できません。

(3)　RPCトレース

RPCトレースも取得できます。ただし，該当バージョンのOpenTP1では，一部の障害情報は取得されません（XATMIインタフェース独自の障害など）。特に，会話型サービスの形態はXATMIインタフェースの通信独自の方法なので，tpsend()とtprecv()などについてのRPCトレースは取得できません。

(4)　オンラインテスタ

XATMIインタフェースを使ったUAPをテストする場合，使えないオンラインテスタの機能があります。オンラインテスタの機能とXATMIインタフェースの関係を次の表に示します。

表5‒5　オンラインテスタの機能とXATMIインタフェースの関係

オンラインテスタの機能

XATMIインタフェースで使う通信プロトコル

TCP/IP

OSI TP

クライアントUAPシミュレート機能

○

×

サーバUAPシミュレート機能

○

×

MCFシミュレート機能

−

−

資源更新処理無効化機能

○

○

運用コマンドシミュレート機能

−

−

テスタファイル作成・編集機能

○

×

UAPトレース情報取得機能

○

○

UAPトレース情報マージ・編集機能

○

○

送信メッセージ編集機能

−

−

デバッガ連動機能

○

×

（凡例）

○：該当する通信プロトコルで使えます。

×：該当する通信プロトコルでは使えません。

−：XATMIインタフェースの通信とは関係しません。

5.2　TXインタフェース（トランザクション制御）

5.2.1　OpenTP1で使えるTXインタフェース

X/Openに準拠したAPI（TX_関数）を，OpenTP1のUAPで使えます。TX_関数でトランザクション制御をするUAPでは，X/Openに準拠した仕様を持つ他社RMを使えます。

(1)　OpenTP1のUAPとTX_関数の関係

OpenTP1のUAPで使えるTX_関数を表5-6に，OpenTP1のUAPとTX_関数との関係を表5-7に示します。

表5‒6　OpenTP1のUAPで使えるTX_関数

TX_関数名

機能

C言語

COBOL言語

tx_begin

TXBEGIN

トランザクションの開始

tx_close

TXCLOSE

リソースマネジャ集合のクローズ

tx_commit

TXCOMMIT

トランザクションのコミット

（連鎖モード：TX_CHAINED指定，非連鎖モード：TX_UNCHAINED指定）

tx_info

TXINFORM

現在のトランザクションに関する情報の返却

tx_open

TXOPEN

リソースマネジャ集合のオープン

tx_rollback

TXROLLBACK

トランザクションのロールバック

（連鎖モード：TX_CHAINED指定，非連鎖モード：TX_UNCHAINED指定）

tx_set_commit_return

TXSETCOMMITRET

commit_return特性の設定

tx_set_transaction_control

TXSETTRANCTL

transaction_control特性の設定

tx_set_transaction_timeout

TXSETTIMEOUT

transaction_timeout特性の設定

表5‒7　OpenTP1のUAPとTX_関数との関係

TX_関数名

SUP

SPP

MHP

オフラインの業務をするUAP

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

トランザクションの処理の範囲でない

トランザクション範囲

トランザクションの処理の範囲でない

トランザクションの処理範囲（ルート）

ルート

ルート以外

tx_begin

○

−

○

−

−

−

−

−

tx_close

○

−

○

−

−

−

−

−

tx_commit

TX_CHAINED指定

−

○

−

○

−

−

−

−

tx_commit

TX_UNCHAINED指定

−

○

−

○

−

−

−

−

tx_info

○

○

○

○

○

−

−

−

tx_open

○

−

○

−

−

−

−

−

tx_rollback

TX_CHAINED指定

−

○

−

○

−

−

−

−

tx_rollback

TX_UNCHAINED指定

−

○

−

○

○

−

−

−

tx_set_commit_return

○

○

○

○

○

−

−

−

tx_set_transaction_control

○

○

○

○

○

−

−

−

tx_set_transaction_timeout

○

○

○

○

○

−

−

−

（凡例）

○：該当する条件で使えます。

−：使えません。

5.2.2　TX_関数の使用方法

(1)　トランザクションの開始

TX_関数でトランザクションを開始させるときは，UAPからは次のように関数を呼び出してください。この順で関数を呼び出すと，ユーザサービス定義のatomic_updateオペランドの指定に関係なく，トランザクションを開始できます。また，ユーザサービス定義でatomic_updateオペランドにYを指定していれば，tx_open()【TXOPEN】とtx_close()【TXCLOSE】を呼び出さなくても，トランザクション処理を開始できます。

SUPでトランザクションを開始する場合

dc_rpc_open()
tx_open()
tx_begin()
      :
      :
tx_commit()（同期点処理）
tx_close()
      :   …この間で，再びtx_open()とtx_close()を呼び出せます。
dc_rpc_close()

SPPでトランザクションを開始する場合

（サービス関数でトランザクションを開始）

dc_rpc_open()
tx_open()
dc_rpc_mainloop()
      :
（サービス関数の処理）
tx_begin()
      :
      :
tx_commit()（同期点処理）
      :
（メイン関数のdc_rpc_mainloop()リターン）
tx_close()
      :
dc_rpc_close()

SPPのサービス関数内でトランザクションを開始させる場合には，dc_rpc_mainloop関数を呼び出す前に，tx_open()を呼び出してください。

(2)　同期点の取得

tx_begin()【TXBEGIN】で開始したトランザクション処理は，同期点を取得する関数（tx_commit()【TXCOMMIT】，またはtx_rollback()【TXROLLBACK】）で必ず完了させてください。

tx_commit()とtx_rollback()には，連鎖モード（TX_CHAINED）と非連鎖モード（TX_UNCHAINED）があります。同期点の取得後に新しいグローバルトランザクションを開始する場合は連鎖モード，開始しないでトランザクション処理を終了させる場合は非連鎖モードを設定します。連鎖モード／非連鎖モードはtransaction_control特性として設定します。transaction_control特性は，tx_set_transaction_control()【TXSETTRANCTL】で設定します。

(3)　トランザクション特性の設定

TX_関数を呼び出すことで，トランザクション処理の特性を設定できます。

(a)　commit_return特性

トランザクションを2相コミットするときに，1相目が完了したときにリターンするか，または2相目まで完了してからリターンするかを設定できます。ただし，OpenTP1の該当バージョンでは2相目まで完了しないうちにリターンする設定はできません。設定した場合はエラーリターンします。commit_return特性は，tx_set_commit_return()【TXSETCOMMITRET】で設定します。

(b)　transaction_control特性

同期点（tx_commit()，tx_rollback()）のあとで，新しいトランザクションを開始させるかどうか（連鎖モードか非連鎖モードか）を設定します。transaction_control特性は，tx_set_transaction_control()【TXSETTRANCTL】で，TX_CHAINEDまたはTX_UNCHAINEDのどちらかを設定します。

(c)　transaction_timeout特性

トランザクションの監視時間を設定できます。transaction_timeout特性は，tx_set_transaction_timeout()【TXSETTIMEOUT】で設定します。システム定義のtrn_expiration_timeの値よりも，tx_set_transaction_timeout()で設定したtransaction_timeout特性が優先されます。

(4)　トランザクションの情報取得

tx_info()【TXINFORM】で，トランザクションブランチIDや，トランザクション特性を格納されている構造体を参照できます。

参照できる構造体の形式を次に示します。

XID                  xid;
COMMIT_RETURN        when_return;
TRANSACTION_CONTROL  transaction_control;
TRANSACTION_TIMEOUT  transaction_timeout;
TRANSACTION_STATE    transaction_state;

(5)　ユーザサービス定義との関連

tx_open()，tx_close()を使うと，ユーザサービス定義のatomic_updateオペランドの値に関係なく，tx_begin()以降の処理をトランザクションとして処理できます。

ただし，tx_begin()を呼び出したUAPからのサービス要求先でトランザクションとして処理する場合は，呼び出し先のサーバUAPのatomic_updateオペランドにYを指定してください。

5.2.3　TX_関数を使用する場合の制限

(1)　TX_関数とOpenTP1の関数を使う場合

OpenTP1の関数は，TX_関数と共用できます。ただし，OpenTP1のトランザクション制御の関数（dc_trn_〜）とTX_関数は併用しないでください。トランザクション制御は必ずどちらか一方の機能で統一してください。

(2)　dc_rpc_open関数とtx_open()の関係

dc_rpc_open関数は，必ずtx_open()よりも先に呼び出してください。dc_rpc_open関数を呼び出さないでtx_open()を呼び出した場合は，TX_ERRORでエラーリターンします。

(3)　dc_rpc_close関数とtx_close()の違い

dc_rpc_close関数を呼び出すと，それ以降はdc_rpc_open関数は呼び出せませんが，tx_open()はtx_close()を呼び出したあとでも再び呼び出せます。トラフィックの関係で，一度UAPを休眠状態にしたい場合などは，一度tx_close()を呼び出してから，再びtx_open()を呼び出します。

(4)　tx_open()，tx_close()とRM固有のオープン，クローズの関係

tx_open()とtx_close()は各RMに対してUAPからアクセスがあること，または終了したことを知らせる関数です。tx_open()またはtx_close()を呼び出すことで，各RMはUAPから処理要求が来ることを知ります。

それに対して，RM固有のオープン，クローズ関数（例えば，dc_dam_open関数，dc_dam_close関数）は，実際の処理の開始と終了を意味する関数です。tx_open()やtx_close()を呼び出しても，RM固有のオープン，クローズ関数が不要になる訳ではありません。

5.2.4　OpenTP1のトランザクション制御関数（dc_trn_〜）との比較

(1)　TX_関数とOpenTP1のトランザクション制御関数（dc_trn_〜）との対応

OpenTP1のトランザクション制御関数（dc_trn〜）とTX_関数の関係を次の表に示します。

表5‒8　OpenTP1のトランザクション制御関数（dc_trn〜）とTX_関数の関係

TX_関数名

OpenTP1のトランザクション制御関数（dc_trn〜）

tx_begin()

dc_trn_begin関数

tx_close()

対応関数なし

tx_commit()（TX_CHAINED指定）

dc_trn_chained_commit関数

tx_commit()（TX_UNCHAINED指定）

dc_trn_unchained_commit関数

tx_info()

dc_trn_info関数

tx_open()

対応関数なし

tx_rollback()（TX_CHAINED指定）

dc_trn_chained_rollback関数

tx_rollback()（TX_UNCHAINED指定）

dc_trn_unchained_rollback関数

tx_set_commit_return()

対応関数なし

tx_set_transaction_control()

対応関数なし

tx_set_transaction_timeout()

対応関数なし

(2)　TX_関数の時間監視

TX_関数では，トランザクションの経過時間をtx_set_transaction_timeout()で監視できます。この場合，システム定義のtrn_expiration_timeオペランドの値よりも，tx_set_transaction_timeout()で設定したtransaction_timeout特性が優先されます。

(a)　時間監視の範囲

tx_begin()から同期点（tx_commit()，tx_rollback()）までの時間監視では，トランザクション内で呼び出したdc_rpc_call関数がリターンするまでの時間を含めるか含めないかを選択できます。トランザクションの監視時間の範囲は，ユーザサービス定義，ユーザサービスデフォルト定義，トランザクションサービス定義のtrn_expiration_time_suspendオペランドで指定できます。trn_expiration_time_suspendオペランドに指定する値とトランザクションの時間監視の詳細については，マニュアル「OpenTP1 システム定義」を参照してください。

6　X/Openに準拠したアプリケーション間通信（TxRPC）

X/Openに準拠したアプリケーション間の通信方法（TxRPCインタフェース）をOpenTP1のアプリケーションプログラムで使う場合の機能について説明します。

6.1　TxRPCインタフェースの通信

TxRPCインタフェースとは，X/Openで規定するクライアント／サーバ形態の通信方法です。OpenTP1のUAPプロセス間で，TxRPCインタフェースの方式で通信できます。ほかのクライアント／サーバ形態の通信と異なり，TxRPCの通信ではユーザが作成した関数をクライアントから呼び出して通信します。ユーザが関数を作成するときは，下位の通信プロトコルを意識する必要はありません。

TxRPCインタフェースの通信の概要を次の図に示します。

図6‒1　TxRPCインタフェースの通信の概要

6.1.1　TxRPC通信の種類

TxRPCの通信方法には，DCE RPCを使うかどうかで次に示す2種類があります。

IDL-only TxRPC

RPC TxRPC

(1)　IDL-only TxRPC

IDLコンパイラから生成されるファイルだけを使ってUAPを作成する方式です。IDL-only TxRPCの場合は，DCEを前提としません。

(2)　RPC TxRPC

通信プロトコルにDCE RPCを使う方式です。このバージョンではRPC TxRPCをサポートしていません。

6.1.2　作成できるアプリケーションプログラム

TxRPCの通信では，次のUAPを作成できます。

クライアントUAP（SUP）

サーバUAP（SPP）

(1)　プロセスタイプ

txidlコマンドのオプションには，作成するUAPのプロセスの型を付けるため，次に示すオプションを付けます。これをプロセスタイプといいます。

ndce：

DCEを使わないプロセスを示します。SUPまたはSPPの場合に指定します。

txidlコマンドの文法については，マニュアル「OpenTP1 プログラム作成リファレンス C言語編」を参照してください。

6.1.3　前提となるライブラリ

TxRPC通信で，前提となるライブラリを次に示します。

SUPまたはSPPを作成する場合

次に示す製品がシステムに組み込んであることが前提です。

TP1/Server Base

6.2　アプリケーションプログラムでできる通信

TxRPCでは，次に示す通信ができます。

同期応答型のトランザクショナルRPC

同期応答型の非トランザクショナルRPC

6.2.1　TxRPCのリモートプロシジャコール

TxRPCのリモートプロシジャコールは，ユーザが作った関数を呼び出す形式です。使えるリモートプロシジャコールの形態は，同期応答型RPCだけです。同期応答型RPC以外のリモートプロシジャコール（非同期応答型RPC，非応答型RPC，会話型RPCなど）は使えません。

TxRPCの通信では，呼び出される関数をマネジャといいます。

OpenTP1のリモートプロシジャコール（dc_rpc_call関数）とTxRPCの通信を併用することもできます。

6.2.2　TxRPCのトランザクション処理

TxRPCのUAPでは，トランザクション処理ができます。UAPの処理からトランザクションを制御する場合は，TX_関数（tx_begin()，tx_rollback()など）を使います。TX_関数のトランザクション制御については，「5.2　TXインタフェース（トランザクション制御）」を参照してください。

(1)　トランザクションが有効な範囲

OpenTP1のTxRPCの場合，IDL-only TxRPCでトランザクション処理を使えます。

(2)　トランザクション属性

トランザクション処理をするTxRPCのUAPのプロセスには，トランザクション属性を指定します。TxRPCには次に示すトランザクション属性があります。

transaction_mandatory

トランザクションを必ず拡張する属性です。トランザクションでない処理からこの属性を指定したUAPを呼び出すと，エラーになります。

transaction_optional

トランザクションの処理から呼び出された場合には，トランザクションとして処理します。トランザクションでない処理から呼び出された場合には，トランザクションでない処理になります。

UAPのトランザクション属性は，インタフェース定義言語ファイル（IDLファイル）に指定します。指定できるのは，transaction_mandatoryかtransaction_optionalのどちらか片方だけです。

アプリケーションプログラムでできる通信を次の図に示します。

図6‒2　アプリケーションプログラムでできる通信

6.2.3　OpenTP1の機能を使うアプリケーションプログラムとTxRPCのアプリケーションプログラムの関連

OpenTP1のリモートプロシジャコール（dc_rpc_call関数）を使うSUP，SPPと，TxRPCを使うサーバUAPでは，次に示す形式で通信できます。

dc_rpc_call関数で呼ばれたSPPは，TxRPCを使って別のSPPを呼び出せます。

TxRPCのサーバUAPからdc_rpc_call関数を使って，SPPへサービスを要求できます。ただし，サーバUAPのプロセスタイプがnbetの場合は，dc_rpc_call関数は使えません。

6.3　TxRPC通信のアプリケーションプログラムを作成する手順

TxRPCの通信を使うUAPの作成手順について説明します。

6.3.1　IDL-only TxRPC通信のUAPを作成する手順

IDL-only TxRPCの通信をするUAPを作成するときの手順は，次のとおりです。

インタフェース定義言語ファイル（IDLファイル）を作成します。

IDLファイルをIDLコンパイラ（txidlコマンド）でコンパイルします。

txidlコマンドで生成されたサーバUAPのテンプレートを基に，プログラムをコーディングします。一緒にクライアントUAPもコーディングします。

txidlコマンドで生成されたスタブとコーディングしたプログラムを，Cコンパイラでコンパイル，リンケージします。

TxRPCの通信のUAPを作成する手順については，マニュアル「OpenTP1 プログラム作成リファレンス C言語編」を参照してください。

IDL-only TxRPCで通信するUAPを作成する手順を次の図に示します。

図6‒3　IDL-only TxRPCで通信するUAPを作成する手順

7　TP1/Multiを使う場合の機能

クラスタ／並列システム形態で，TP1/Multiを使う場合の機能について説明します。

7.1　クラスタ／並列システム形態のアプリケーションプログラム

OpenTP1をクラスタ／並列システムに適用する場合のUAPについて説明します。

7.1.1　アプリケーションプログラムを使えるノード

マルチノード機能を使った環境では，被アーカイブジャーナルノードでだけUAP（ユーザサーバ）を使えます。アーカイブジャーナルノードでは，ユーザサーバを使えません。

7.1.2　アプリケーションプログラムを実行する前提条件

クラスタ／並列システム向けの機能を実行するUAPがあるOpenTP1ノードには，次の前提条件があります。

TP1/Multiが組み込まれている

システム共通定義のmulti_node_optionオペランドにYを指定している

ただし，次に示す機能は，TP1/Multiを組み込んでいなくても，システム共通定義のmulti_node_optionオペランドにYを指定していなくてもかまいません。

ユーザサーバの状態を取得する関数（dc_adm_get_sv_status〜関数）で，自ノードのユーザサーバの状態を取得する場合

自OpenTP1ノードのノード識別子を取得する関数（dc_adm_get_node_id関数）を使う場合

クラスタ／並列システム形態のアプリケーションプログラムの概要を次の図に示します。

図7‒1　クラスタ／並列システム形態のアプリケーションプログラムの概要

7.2　アプリケーションプログラムでできる機能

クラスタ／並列システム形態のOpenTP1のUAPから，OpenTP1の関数を使ってできる機能について説明します。

7.2.1　OpenTP1ノードの状態の取得

UAPから関数を呼び出して，クラスタ／並列システムを構成するOpenTP1ノードの状態を取得できます。OpenTP1ノードの状態を取得することで，マルチノードエリア，またはマルチノードサブエリアの状態をUAPで監視できます。

取得できる状態を次に示します。

OpenTP1ノードが開始していません。

OpenTP1ノードが停止中です。または異常終了中です。

OpenTP1ノードは正常開始中です。

OpenTP1ノードは再開始（リラン）中です。

OpenTP1ノードはオンライン中です。

OpenTP1ノードは正常終了処理中です。

OpenTP1ノードは計画停止Aで終了処理中です。

OpenTP1ノードは計画停止Bで終了処理中です。

OpenTP1ノードの状態を取得するには，ノード状態を連続して取得する方法と，指定したOpenTP1ノードの状態だけを取得する方法があります。

(1)　OpenTP1ノードの状態を連続して取得する方法

マルチノードエリア，またはマルチノードサブエリア単位に，そのエリアにあるすべてのOpenTP1ノードの状態を取得します。

連続して状態を取得する場合は，取得したいマルチノードエリア，またはマルチノードサブエリアの識別子を指定したdc_adm_get_nd_status_begin関数を使います。この関数を呼び出すと，指定したエリアにあるOpenTP1ノードの個数がリターンされます。次に，dc_adm_get_nd_status_next関数を呼び出して，OpenTP1ノードの状態を取得します。該当するOpenTP1ノードがなくなるまでdc_adm_get_nd_status_next関数を呼び出してから，最後にdc_adm_get_nd_status_done関数を呼び出して状態の取得を終了します。

dc_adm_get_nd_status_begin関数を呼び出したあとで，もう一度dc_adm_get_nd_status_begin関数を呼び出すこと（dc_adm_get_nd_status_begin関数のネスト）はできません。

OpenTP1ノードの状態を連続して取得する手順を次の図に示します。

図7‒2　OpenTP1ノードの状態を連続して取得する手順

(2)　指定したOpenTP1ノードの状態を取得する方法

一つのOpenTP1ノードの状態を取得する場合は，dc_adm_get_nd_status関数を呼び出します。この関数を呼び出すと，関数に設定したOpenTP1ノードのノード識別子に関する状態を取得できます。

7.2.2　ユーザサーバの状態の取得

UAPから関数を呼び出して，クラスタ／並列システムを構成するOpenTP1ノードのユーザサーバの状態を取得できます。ユーザサーバの状態を取得することで，UAPでマルチノードエリア，またはマルチノードサブエリアのユーザサーバの状態を監視できます。

取得できる状態を次に示します。

ユーザサーバが停止中です。または異常終了中です。

ユーザサーバは正常開始中です。

ユーザサーバは再開始中です。

ユーザサーバはオンライン中です。

ユーザサーバは正常終了処理中です。

ユーザサーバの状態を取得する場合，連続して取得する方法と，指定したユーザサーバの状態だけを取得する方法があります。

(1)　ユーザサーバの状態を連続して取得する方法

OpenTP1ノードのノード識別子単位に，そのノードにあるすべてのユーザサーバの状態を取得します。

連続して状態を取得する場合は，取得したいノード識別子を指定したdc_adm_get_sv_status_begin関数を呼び出します。この関数を呼び出すと，指定したOpenTP1ノードにあるユーザサーバの個数がリターンされます。次に，dc_adm_get_sv_status_next関数を呼び出して，ユーザサーバの状態を取得します。該当するユーザサーバがなくなるまでdc_adm_get_sv_status_next関数を呼び出してから，最後にdc_adm_get_sv_status_done関数を呼び出して状態の取得を終了します。

dc_adm_get_sv_status_begin関数を呼び出したあとで，もう一度 dc_adm_get_sv_status_begin関数を呼び出すこと（dc_adm_get_sv_status_begin関数のネスト）はできません。

ユーザサーバの状態を連続して取得する手順を次の図に示します。

図7‒3　ユーザサーバの状態を連続して取得する手順

(2)　指定したユーザサーバの状態を取得する方法

一つのユーザサーバの状態を取得する場合は，dc_adm_get_sv_status関数を呼び出します。この関数を呼び出すと，関数に設定したノード識別子のユーザサーバに関する状態を取得できます。

7.2.3　OpenTP1ノードのノード識別子の取得

UAPから関数を呼び出して，マルチノードエリア，またはマルチノードサブエリアにあるすべてのノード識別子を取得できます。ノード識別子を取得して，マルチノードエリア，またはマルチノードサブエリアを構成するOpenTP1ノードをUAPで知ることができます。

OpenTP1ノードのノード識別子を取得する場合，連続して取得する方法と，指定したOpenTP1ノードのノード識別子だけを取得する方法があります。

(1)　OpenTP1ノードのノード識別子を連続して取得する方法

マルチノードエリア，またはマルチノードサブエリア単位に，そのエリアにあるすべてのOpenTP1ノードのノード識別子を取得します。連続してノード識別子を取得する場合は，取得したいエリアを指定したdc_adm_get_nodeconf_begin関数を呼び出します。この関数を呼び出すと，指定したエリアにあるOpenTP1ノードの個数がリターンされます。次に，dc_adm_get_nodeconf_next関数を呼び出して，OpenTP1ノードのノード識別子を取得します。該当するOpenTP1ノードがなくなるまでdc_adm_get_nodeconf_next関数を呼び出してから，最後にdc_adm_get_nodeconf_done関数を呼び出して状態の取得を終了します。

dc_adm_get_nodeconf_begin関数を呼び出したあとで，もう一度 dc_adm_get_nodeconf_begin関数を呼び出すこと（dc_adm_get_nodeconf_begin関数のネスト）はできません。

OpenTP1ノードのノード識別子を連続して取得する手順を次の図に示します。

図7‒4　OpenTP1ノードのノード識別子を連続して取得する手順

(2)　自OpenTP1ノードのノード識別子を取得する方法

UAPを実行しているOpenTP1ノードのノード識別子を取得する場合は，dc_adm_get_node_id関数を呼び出します。この関数を呼び出すと，自OpenTP1ノードのノード識別子を取得できます。

7.3　マルチノード機能の関数を使える条件

マルチノード機能の関数を使える条件を次の表に示します。

表7‒1　マルチノード機能の関数を使える条件

マルチノードの関数と引数node_idの指定

TP1/Multiを組み込んでいる

TP1/Multiを組み込んでいない

multi_node_optionの指定

multi_node_optionの指定

Y

N

Y

N

dc_adm_get_nd_status_begin

任意

○

×

−

×

dc_adm_get_nd_status_next

任意

○

×

−

×

dc_adm_get_nd_status_done

任意

○

×

−

×

dc_adm_get_nd_status

'*'指定

○

×

−

×

自node_id指定

○

×

−

×

他node_id指定

○

×

−

×

dc_adm_get_sv_status_begin

'*'指定

○

○

−

○

自node_id指定

○

○

−

○

他node_id指定

○

×

−

×

dc_adm_get_sv_status_next

'*'指定

○

○

−

○

自node_id指定

○

○

−

○

他node_id指定

○

×

−

×

dc_adm_get_sv_status_done

'*'指定

○

○

−

○

自node_id指定

○

○

−

○

他node_id指定

○

×

−

×

dc_adm_get_sv_status

'*'指定

○

○

−

○

自node_id指定

○

○

−

○

他node_id指定

○

×

−

×

dc_adm_get_nodeconf_begin

任意

○

×

−

×

dc_adm_get_nodeconf_next

任意

○

×

−

×

dc_adm_get_nodeconf_done

任意

○

×

−

×

dc_adm_get_node_id

任意

○

○

−

○

（凡例）

○：該当する条件で使えます。

×：該当する条件では使えません。

−：該当する条件で関数を呼び出すと，OpenTP1が異常終了します。

8　OpenTP1のサンプル

OpenTP1で提供するサンプルの使い方について説明します。

8.1　サンプルの概要

システムをより手軽に構築するため，OpenTP1ではサンプル（例題）を使えます。サンプルを使うと，次のような利点があります。

OpenTP1を組み込んでから確立するまでの負担を減らせます。

システムの運用を支援するためのツールが使えます。

UAPをCOBOL言語でコーディングするときに，テンプレートが使えます。

8.1.1　サンプルの種類

OpenTP1のサンプルを次に示します。

Baseサンプル

TP1/Server Baseと一緒に提供するサンプルです。

DAMサンプル

TP1/FS/Direct Accessと一緒に提供するサンプルです。

TAMサンプル

TP1/FS/Table Accessと一緒に提供するサンプルです。

MCFサンプル

メッセージ制御機能（TP1/Message Control，TP1/NET/Library，および通信プロトコル対応製品）と一緒に提供するサンプルです。

delvcmdコマンド

マルチOpenTP1に対するコマンドを振り分けます。

COBOL言語用テンプレート

UAPをCOBOL言語でコーディングするときに使える，データ部のテンプレートです。

サンプルシナリオテンプレート

シナリオテンプレートを利用したシステムの運用時に使用するサンプルシナリオテンプレートです。このサンプルを使用するには，シナリオテンプレートを利用したシステムの前提となるJP1製品（JP1/AJS，JP1/AJS2 - Scenario Operation，JP1/Base）が必要です。

リアルタイム取得項目定義テンプレート

リアルタイム統計情報サービスで使用するテンプレートです。

それぞれのサンプルは独立していて，ディレクトリごとに分けて格納してあります。サンプルを使うときは，それぞれ独立して使えます。

(1)　アプリケーションプログラムからアクセスするファイル

Baseサンプル，DAMサンプル，TAMサンプルは，サンプルプログラム（UAP）とOpenTP1ファイルシステムを使えます。UAPは，同じ形態のプログラムを使っています。ただし，UAPで使うデータベースを格納する場所は，サンプルによって異なります。

Baseサンプルのデータベース：メモリテーブル上

DAMサンプルのデータベース：DAMファイル

TAMサンプルのデータベース：TAMテーブル

上記のサンプルのUAPでは，データベースに対して，データの参照や更新などのアクセスをします。このアクセス手順で，OpenTP1のAPIを使う方法がわかります。

8.1.2　サンプルのディレクトリ構成

OpenTP1のサンプルで使うファイルについて説明します。OpenTP1のサンプルが格納されているディレクトリを次の図に示します。

図8‒1　サンプルを格納するディレクトリ構成

注※1

$DCDIRは，OpenTP1ホームディレクトリを示す環境変数です。OpenTP1のサンプル一式をデフォルトのOpenTP1ホームディレクトリ以外のディレクトリにコピーした場合は，そのディレクトリ名を示します。OpenTP1のサンプル一式をコピーしていない場合は，examples/ディレクトリは$DCDIRの下にあります。

注※2

betranfileは，ツール用のサンプルのコマンドを実行すると作成されます。初期状態では作成されていません。

注※3

OpenTP1のインストールディレクトリはOSによって異なります。

(1)　$DCDIR直下のexamples/ディレクトリの内容

$DCDIR直下のexamples/ディレクトリには，サンプルで使うディレクトリが格納してあります。examples/ディレクトリの各ファイルの内容を次に示します。

base/

Baseサンプルのファイルが格納してあるディレクトリ

dam/

DAMサンプルのファイルが格納してあるディレクトリ

tam/

TAMサンプルのファイルが格納してあるディレクトリ

tools/

サンプルで共通に使うツールが格納してあるディレクトリ（ツールディレクトリ）

mcf/

メッセージ制御機能（MCF）サンプルのファイルが格納してあるディレクトリ

COBOL/

COBOL言語用テンプレートを格納するディレクトリ

(a)　base/，dam/，tam/ディレクトリの内容

base/，dam/，tam/ディレクトリに格納してあるディレクトリ，およびファイルを次に示します。

aplib/

サンプルのUAPが格納されているディレクトリ

c/

各サンプルのUAPのソースファイル（C言語）が格納されているディレクトリ

cobol/

各サンプルのUAPのソースファイル（COBOL言語）が格納されているディレクトリ

conf/

各サンプル用の定義ファイルが格納されているディレクトリ

betranfile

各サンプル用のOpenTP1ファイルシステム（このファイルの内容はtools/ディレクトリのツールを使って作成します）

(b)　tools/ディレクトリの内容

tools/ディレクトリの各ファイルの内容を次に示します。

base_mkfs

Baseサンプル用のOpenTP1ファイルシステムを作成するシェルファイル

dam_mkfs

DAMサンプル用のOpenTP1ファイルシステムを作成するシェルファイル

apbat

DAMサンプル用でDAMファイルを作成するファイル（dam_mkfsで使います）。このファイルは，makeコマンドを実行してUAPの実行形式ファイルを作成したときに作成されます。実行形式ファイルの作成方法については，「8.3.2(1)(b)　UAPの実行形式ファイルの作成」を参照してください。

tam_mkfs

TAMサンプル用のOpenTP1ファイルシステムを作成するシェルファイル

tamdata

TAMテーブル作成用のデータファイル（tam_mkfsで使います）

chconf

定義ファイルを修正するコマンド（$DCDIRを実際のOpenTP1ホームディレクトリに変更するときに使います）

bkconf

chconfで変更した定義ファイルを元に戻すコマンド

delvcmd

マルチOpenTP1形態のノードにコマンドを振り分けるコマンド。delvcmdコマンドについては，「8.7　マルチOpenTP1のコマンドを振り分けるサンプル」を参照してください。

(c)　mcf/ディレクトリの内容

mcf/ディレクトリの構成については，「8.6　MCFサンプルの使い方」を参照してください。

(d)　COBOL/ディレクトリの内容

COBOL/ディレクトリの構成については，「8.8　COBOL言語用テンプレート」を参照してください。

(2)　$DCDIR直下のrts_template/ディレクトリの内容

$DCDIR直下のrts_template/ディレクトリには，リアルタイム統計情報サービスで使うディレクトリが格納してあります。rts_template/ディレクトリの各ファイルの内容を次に示します。

(a)　examples/ディレクトリの内容

examples/ディレクトリの各ファイルの内容を次に示します。

conf/

リアルタイム統計情報サービス用のリアルタイム取得項目定義ファイルが格納されているディレクトリ

base_itm

BASE用のリアルタイム取得項目定義ファイル

dam_itm

DAM用のリアルタイム取得項目定義ファイル

tam_itm

TAM用のリアルタイム取得項目定義ファイル

all_itm

すべての統計情報を取得するリアルタイム取得項目定義ファイル

none_itm

すべての統計情報を取得しないリアルタイム取得項目定義ファイル

mcfs_itm

MCF用のリアルタイム取得項目定義ファイル（システム全体，サーバ，サービス単位に取得する項目）

mcfl_itm

MCF用のリアルタイム取得項目定義ファイル（論理端末単位に取得する項目）

mcfg_itm

MCF用のリアルタイム取得項目定義ファイル（サービスグループ単位に取得する項目）

(3)　インストールディレクトリ直下のjp1_template/ディレクトリの内容

インストールディレクトリ直下のjp1_template/ディレクトリには，サンプルシナリオテンプレートで使うディレクトリが格納してあります。jp1_template/ディレクトリの各ファイルの内容を次に示します。

examples/

スケールアウトのサンプルシナリオテンプレートで使用するファイルが格納されているディレクトリ

(a)　examples/ディレクトリの内容

examples/ディレクトリの各ディレクトリの内容を次に示します。

aplib/

シナリオテンプレートのサンプルプログラムのロードモジュール（source/ディレクトリ下のソースファイルに対するロードモジュール）が格納されているディレクトリ

conf/

サンプルシナリオテンプレート用の定義ファイルが格納されているディレクトリ

tools/

サンプルシナリオテンプレートで使用するシェルファイルが格納されているディレクトリ

dcjset_conf

サンプルシナリオテンプレート用のOpenTP1の環境設定をするシェルファイル

dcj_mkfs

サンプルシナリオテンプレート用のOpenTP1のファイルシステムを作成するシェルファイル

dcjmk_dcdir

サンプルシナリオテンプレート用のOpenTP1のディレクトリを作成するシェルファイル

source/

シナリオテンプレートのサンプルプログラム（UAP）が格納されているディレクトリ。サンプルシナリオテンプレートでは，Baseサンプルをサンプルプログラムとして使用しています。Baseサンプルの仕様については，「8.5　サンプルプログラムの仕様」を参照してください。

8.1.3　サンプルの説明方法

サンプルの説明で使う，コマンド入力例を表記する形式について説明します。コマンド入力例は，次のように表記します。

ユーザが入力するコマンドは，アンダーライン（　）で示します。上の例は「画面にプロンプトが表示されているのを確認した上で，dcstartコマンドを入力してリターンキーを押す」ことを示します。

8.2　Baseサンプルの使い方

Baseサンプルを使う手順について説明します。サンプルを使う手順の概要を次の図に示します。

図8‒2　サンプルを使う手順の概要（Baseサンプル：スタブを使用する場合）

図8‒3　サンプルを使う手順の概要（Baseサンプル：サービス関数動的ローディング機能を使用する場合）

8.2.1　サンプル共通の作業（Baseサンプル）

OpenTP1の3種類のサンプル（Baseサンプル，DAMサンプル，TAMサンプル）に共通する準備手順について説明します。

サンプルを使う前には，OpenTP1の製品（TP1/Server Base，TP1/FS/Direct Access，TP1/FS/Table Access）を組み込んでおきます。この作業は，OpenTP1管理者が操作します。ここまでは，通常のOpenTP1の組み込み手順と同じです。

(1)　環境変数DCDIRにOpenTP1ホームディレクトリを設定します

環境変数DCDIRにOpenTP1ホームディレクトリを設定します。

（例）OpenTP1ホームディレクトリを/usr/betranにする場合

cshのとき

%  setenv  DCDIR  /usr/betran  <CR>

bashのとき

$  export DCDIR=/usr/betran  <CR>

(2)　OpenTP1管理者のコマンドサーチパスにディレクトリを追加します

OpenTP1管理者のコマンドのサーチパスに，OpenTP1のコマンドのサーチパスと，サンプルで使うコマンドのサーチパスを追加します。

$DCDIR/bin：OpenTP1のコマンドのサーチパスです。

$DCDIR/examples/tools：サンプル用のツールのサーチパスです。

(3)　OpenTP1のサンプル一式をコピーします

OpenTP1ホームディレクトリを/BeTRAN以外に変更した場合は，OpenTP1ホームディレクトリの環境に，サンプル一式をコピーします。OpenTP1ホームディレクトリを/BeTRANのままでサンプルを使う場合は，コピーする必要はありません。コピーするときは，UNIXのcp，tarなどのコマンドを使います。

コピーするときは，OpenTP1ホームディレクトリの下に，「8.1.2　サンプルのディレクトリ構成」で示す構成になるようにしてください。これ以外の構成とした場合，システムの動作は保証しません。

（例）

OpenTP1を組み込んだディレクトリが/BeTRANで，そのディレクトリからOpenTP1ホームディレクトリにサンプルをコピーする場合（cpコマンドを使います）

%  cp  -R  /BeTRAN/examples  $DCDIR  <CR>

これで，OpenTP1のサンプルの環境設定は終了です。続けて，各サンプル固有の作業を実行します。

8.2.2　Baseサンプル固有の作業（スタブを使用する場合）

Baseサンプル固有の準備手順について説明します。ここの記述では，次の条件でサンプルを使うものとします。

使うシェル：Cシェル

OpenTP1ホームディレクトリ：/usr/betran

(1)　アプリケーションプログラムを作成します

BaseサンプルのUAPを作成する手順を示します。サンプルプログラムを作成するときは，UNIXのツールmakeコマンドを使います。サンプルでは，専用のmakefileをBaseサンプルのディレクトリに作成してあります。

makeコマンドは，aplib/ディレクトリにあるc/またはcobol/ディレクトリをカレントディレクトリとして実行します。makeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1のセットアップについては，「8.2.3(1)　OpenTP1をセットアップします」を参照してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

C言語のUAPを作成するコマンド入力例を次に示します。

%  chdir  $DCDIR/examples/base/aplib/c  <CR>
%  make   <CR>

このコマンドを実行すると，aplib/ディレクトリの下にbasesppおよびbasesupというUAPの実行形式ファイル（C言語）が作成されます。

(2)　システム定義を修正します

サンプルでは，システム定義の手間を省くために，定義ファイルの例を提供しています。ただし，一部の定義ファイルは，実際のOpenTP1ホームディレクトリを絶対パス名で指定する必要があります。

(a)　OpenTP1ホームディレクトリの定義を変更する手順

実際のOpenTP1ホームディレクトリに修正するときは，変更用のツールchconfコマンドを使います。このコマンドを実行すると，定義ファイルの項目でOpenTP1ホームディレクトリが$DCDIRとなっている部分を，実際のOpenTP1ホームディレクトリ（例えば，/usr/betran）に変更できます。

chconfコマンドは，$DCDIR/examples/base/conf/ディレクトリに移動してから実行します。コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/base/conf  <CR>
%  chconf  <CR>

chconfコマンドを実行すると，定義ファイルの内容が変更されます。変更する定義ファイルと変更する内容を次の表に示します。実際のOpenTP1ホームディレクトリに変更される部分を太字で示します。

表8‒1　変更する定義ファイルと変更する内容（Baseサンプル）

変更する定義ファイル

変更する内容

env

putenv DCCONFPATH $DCDIR/examples/base/conf

prc

putenv prcsvpath $DCDIR/examples/base/aplib

sts

物理ファイル名：$DCDIR/examples/base/betranfile/×××

sysjnl

物理ファイル名：$DCDIR/examples/base/betranfile/×××

cdtrn

物理ファイル名：$DCDIR/examples/base/betranfile/×××

このツール（chconfコマンド）を実行する前には，環境変数DCDIRにあらかじめOpenTP1ホームディレクトリを設定しておいてください。設定していないと正常に変更できません。

(b)　変更したOpenTP1ホームディレクトリを元に戻す方法

変更したOpenTP1ホームディレクトリを元に戻すときは，変更取り消し用のツールbkconfコマンドを使います。chconfコマンドで変更しようとした内容を，初期状態に戻します。

chconfコマンドでシステム定義を正常に変更できなかった場合は，すぐにbkconfコマンドを実行してください。

コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/base/conf  <CR>
%  bkconf  <CR>

(3)　環境変数と定義ファイルを設定します

作成したサンプルUAPとサンプルのシステム定義で，OpenTP1システムを開始する手順について説明します。

(a)　環境変数DCCONFPATHの設定

環境変数DCCONFPATHに，定義ファイルを格納しているディレクトリを設定します。この設定をすると，OpenTP1が定義ファイルの内容を認識できるようになります。

コマンド入力例を次に示します。

cshの場合

%  setenv  DCCONFPATH  $DCDIR/examples/base/conf  <CR>

bashの場合

$  export  DCCONFPATH=$DCDIR/examples/base/conf  <CR>

(b)　定義ファイルenvのコピー

定義ファイルのうち，envファイルだけは，$DCDIR/confからOpenTP1に読み込まれます。そのため，サンプルとして作成したenv定義ファイルを$DCDIR/confへ移動します。

$DCDIR/conf/ディレクトリにenv定義ファイルを作成している場合は，上書きされてしまうので，必要であれば退避しておいてください。

コマンド入力例を次に示します。

%  cp  $DCDIR/examples/base/conf/env  $DCDIR/conf  <CR>

(c)　OpenTP1ファイルシステムの初期化

OpenTP1ファイルシステムを初期化します。Baseサンプル用のOpenTP1ファイルシステムの初期化は，base_mkfsというシェルファイルを実行します。

コマンド入力例を次に示します。

%  base_mkfs  <CR>

このシェルファイルを実行すると，$DCDIR/examples/base/ディレクトリの下にbetranfileというファイルが生成され，この下にOpenTP1ファイルシステムが構築されます。

8.2.3　OpenTP1を使うための作業（スタブを使用する場合）

システム定義を修正し終わったら，OpenTP1を使うための作業をします。

(1)　OpenTP1をセットアップします

OpenTP1をセットアップするときは，dcsetupコマンドを実行します。dcsetupコマンドは，/BeTRAN/bin/ディレクトリの下にあります。

コマンド入力例を次に示します。

%  /BeTRAN/bin/dcsetup  OpenTP1ホームディレクトリ名  <CR>

セットアップの作業は，スーパユーザが操作します。dcsetupコマンドは，絶対パス名で実行してください。dcsetupコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。

サンプルプログラムを作成するmakeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

(2)　OpenTP1システムとユーザサーバを起動します

OpenTP1システムとユーザサーバを起動する手順について説明します。

(a)　OpenTP1システムの起動

OpenTP1システムをdcstartコマンドで起動します。

コマンド入力例を次に示します。

%  dcstart  <CR>

(b)　ユーザサーバ（UAP）の起動

dcsvstartコマンドで，作成したUAPを起動します。サーバUAP（SPP）を起動してから，クライアントUAP（SUP）を起動します。

コマンド入力例を次に示します。

%  dcsvstart -u basespp  <CR>

  basesppがオンライン状態になったことがメッセージログで出力されます。

%  dcsvstart -u basesup  <CR>

  basesupがオンライン状態になったことがメッセージログで出力されます。

  ユーザサーバ（UAP）の処理経過が出力されます。

サーバUAP（SPP）は，ユーザサービス構成定義でOpenTP1システムの起動時に自動的に起動することもできます。

(3)　OpenTP1ファイルシステムの内容一覧

OpenTP1ファイルシステム作成ツールbase_mkfsコマンドを実行すると，$DCDIR/examples/base/betranfileファイル上にOpenTP1ファイルシステムが作成されます。作成されるOpenTP1ファイルシステムの内容を次の表に示します。

表8‒2　OpenTP1ファイルシステムの内容一覧（Baseサンプル）

ファイル名

使う目的となるファイル

レコード長※

レコード数

jnl01

システムジャーナルファイル

4096バイト

50レコード

jnl02

システムジャーナルファイル

4096バイト

50レコード

jnl03

システムジャーナルファイル

4096バイト

50レコード

stsfil01

ステータスファイル

4608バイト

50レコード

stsfil02

ステータスファイル

4608バイト

50レコード

stsfil03

ステータスファイル

4608バイト

50レコード

stsfil04

ステータスファイル

4608バイト

50レコード

cpdf01

チェックポイントダンプファイル

4096バイト

256レコード

cpdf02

チェックポイントダンプファイル

4096バイト

256レコード

cpdf03

チェックポイントダンプファイル

4096バイト

256レコード

注※

ここで示すレコード長は，省略時仮定値です。

(4)　サンプルUAPの入れ替え

サンプルのUAPは，次に示す手順で入れ替えてください。

OpenTP1システムを停止します。

dcsetupコマンドに-dオプションを付けて実行して，いったんOpenTP1をOSから削除します。

「8.2　Baseサンプルの使い方」で示す手順で，使いたいサンプルのUAPを設定し直します。

UAPを実行します。

8.2.4　Baseサンプル固有の作業（サービス関数動的ローディング機能を使用する場合）

サービス関数動的ローディング機能を使用する場合の，Baseサンプル固有の準備手順について説明します。ここの記述では，次の条件でサンプルを使うものとします。

使うシェル：Cシェル

OpenTP1ホームディレクトリ：/usr/betran

(1)　アプリケーションプログラムを作成します

サービス関数動的ローディング機能を使用する場合の，BaseサンプルのUAPを作成する手順を示します。サンプルプログラムを作成するときは，UNIXのツールmakeコマンドを使います。サンプルでは，専用のmakefileをBaseサンプルのディレクトリに作成してあります。

makeコマンドは，aplib/ディレクトリにあるc/またはcobol/ディレクトリをカレントディレクトリとして実行します。makeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1のセットアップについては，「8.2.5(1)　OpenTP1をセットアップします」を参照してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

C言語のUAPを作成するコマンド入力例を次に示します。

%  chdir  $DCDIR/examples/base/aplib/c  <CR>
%  make   -f make_svdl  <CR>

このコマンドを実行すると，aplib/ディレクトリの下にbasespp2およびbasesup2というUAPの実行形式ファイル（C言語）が作成されます。

(2)　システム定義を修正します

サンプルでは，システム定義の手間を省くために，定義ファイルの例を提供しています。ただし，一部の定義ファイルは，実際のOpenTP1ホームディレクトリを絶対パス名で指定する必要があります。

(a)　OpenTP1ホームディレクトリの定義を変更する手順

実際のOpenTP1ホームディレクトリに修正するときは，変更用のツールchconfコマンドを使います。このコマンドを実行すると，定義ファイルの項目でOpenTP1ホームディレクトリが$DCDIRとなっている部分を，実際のOpenTP1ホームディレクトリ（例えば，/usr/betran）に変更できます。

chconfコマンドは，$DCDIR/examples/base/conf/ディレクトリに移動してから実行します。コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/base/conf  <CR>
%  chconf  <CR>

chconfコマンドを実行すると，定義ファイルの内容が変更されます。変更する定義ファイルと変更する内容を次の表に示します。実際のOpenTP1ホームディレクトリに変更される部分を太字で示します。

表8‒3　変更する定義ファイルと変更する内容（Baseサンプル）

変更する定義ファイル

変更する内容

env

putenv DCCONFPATH $DCDIR/examples/base/conf

prc

putenv prcsvpath $DCDIR/examples/base/aplib

sts

物理ファイル名：$DCDIR/examples/base/betranfile/×××

sysjnl

物理ファイル名：$DCDIR/examples/base/betranfile/×××

cdtrn

物理ファイル名：$DCDIR/examples/base/betranfile/×××

このツール（chconfコマンド）を実行する前には，環境変数DCDIRにあらかじめOpenTP1ホームディレクトリを設定しておいてください。設定していないと正常に変更できません。

なお，basespp2およびBASESPP2のserviceオペランドに指定された，$DCDIRを含むUAP共用ライブラリ名は，環境変数を使用して指定できるため，chconfコマンドを実行しても定義ファイルの内容は変更されません。

(b)　変更したOpenTP1ホームディレクトリを元に戻す方法

変更したOpenTP1ホームディレクトリを元に戻すときは，変更取り消し用のツールbkconfコマンドを使います。chconfコマンドで変更しようとした内容を，初期状態に戻します。

chconfコマンドでシステム定義を正常に変更できなかった場合は，すぐにbkconfコマンドを実行してください。

コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/base/conf  <CR>
%  bkconf  <CR>

(3)　環境変数と定義ファイルを設定します

作成したサンプルUAPとサンプルのシステム定義で，OpenTP1システムを開始する手順について説明します。

(a)　環境変数DCCONFPATHの設定

環境変数DCCONFPATHに，定義ファイルを格納しているディレクトリを設定します。この設定をすると，OpenTP1が定義ファイルの内容を認識できるようになります。

コマンド入力例を次に示します。

cshの場合

%  setenv  DCCONFPATH  $DCDIR/examples/base/conf  <CR>

bashの場合

$  export  DCCONFPATH=$DCDIR/examples/base/conf  <CR>

(b)　定義ファイルenvのコピー

定義ファイルのうち，envファイルだけは，$DCDIR/confからOpenTP1に読み込まれます。そのため，サンプルとして作成したenv定義ファイルを$DCDIR/confへ移動します。

$DCDIR/conf/ディレクトリにenv定義ファイルを作成している場合は，上書きされてしまうので，必要であれば退避しておいてください。

コマンド入力例を次に示します。

%  cp  $DCDIR/examples/base/conf/env  $DCDIR/conf  <CR>

(c)　OpenTP1ファイルシステムの初期化

OpenTP1ファイルシステムを初期化します。Baseサンプル用のOpenTP1ファイルシステムの初期化は，base_mkfsというシェルファイルを実行します。

コマンド入力例を次に示します。

%  base_mkfs  <CR>

このシェルファイルを実行すると，$DCDIR/examples/base/ディレクトリの下にbetranfileというファイルが生成され，この下にOpenTP1ファイルシステムが構築されます。

8.2.5　OpenTP1を使うための作業（サービス関数動的ローディング機能を使用する場合）

システム定義を修正し終わったら，OpenTP1を使うための作業をします。

(1)　OpenTP1をセットアップします

OpenTP1をセットアップするときは，dcsetupコマンドを実行します。dcsetupコマンドは，/BeTRAN/bin/ディレクトリの下にあります。

コマンド入力例を次に示します。

%  /BeTRAN/bin/dcsetup  OpenTP1ホームディレクトリ名  <CR>

セットアップの作業は，スーパユーザが操作します。dcsetupコマンドは，絶対パス名で実行してください。dcsetupコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。

サンプルプログラムを作成するmakeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

(2)　OpenTP1システムとユーザサーバを起動します

OpenTP1システムとユーザサーバを起動する手順について説明します。

(a)　OpenTP1システムの起動

OpenTP1システムをdcstartコマンドで起動します。

コマンド入力例を次に示します。

%  dcstart  <CR>

(b)　ユーザサーバ（UAP）の起動

dcsvstartコマンドで，作成したUAPを起動します。サーバUAP（SPP）を起動してから，クライアントUAP（SUP）を起動します。

コマンド入力例を次に示します。

%  dcsvstart -u basespp2  <CR>

  basespp2がオンライン状態になったことがメッセージログで出力されます。

%  dcsvstart -u basesup2  <CR>

  basesup2がオンライン状態になったことがメッセージログで出力されます。

  ユーザサーバ（UAP）の処理経過が出力されます。

サーバUAP（SPP）は，ユーザサービス構成定義でOpenTP1システムの起動時に自動的に起動することもできます。

(3)　OpenTP1ファイルシステムの内容一覧

OpenTP1ファイルシステム作成ツールbase_mkfsコマンドを実行すると，$DCDIR/examples/base/betranfileファイル上にOpenTP1ファイルシステムが作成されます。作成されるOpenTP1ファイルシステムの内容を次の表に示します。

表8‒4　OpenTP1ファイルシステムの内容一覧（Baseサンプル）

ファイル名

使う目的となるファイル

レコード長※

レコード数

jnl01

システムジャーナルファイル

4096バイト

50レコード

jnl02

システムジャーナルファイル

4096バイト

50レコード

jnl03

システムジャーナルファイル

4096バイト

50レコード

stsfil01

ステータスファイル

4608バイト

50レコード

stsfil02

ステータスファイル

4608バイト

50レコード

stsfil03

ステータスファイル

4608バイト

50レコード

stsfil04

ステータスファイル

4608バイト

50レコード

cpdf01

チェックポイントダンプファイル

4096バイト

256レコード

cpdf02

チェックポイントダンプファイル

4096バイト

256レコード

cpdf03

チェックポイントダンプファイル

4096バイト

256レコード

注※

ここで示すレコード長は，省略時仮定値です。

(4)　サンプルUAPの入れ替え

サンプルのUAPは，次に示す手順で入れ替えてください。

OpenTP1システムを停止します。

dcsetupコマンドに-dオプションを付けて実行して，いったんOpenTP1をOSから削除します。

「8.2　Baseサンプルの使い方」で示す手順で，使いたいサンプルのUAPを設定し直します。

UAPを実行します。

8.3　DAMサンプルの使い方

DAMサンプルを使う手順について説明します。サンプルを使う手順の概要を次の図に示します。

図8‒4　サンプルを使う手順の概要（DAMサンプル）

8.3.1　サンプル共通の作業（DAMサンプル）

次に示す手順は，OpenTP1の3種類のサンプルに共通する準備です。

環境変数DCDIRにOpenTP1ホームディレクトリを設定します

OpenTP1管理者のコマンドサーチパスにディレクトリを追加します

OpenTP1のサンプル一式をコピーします

上記の手順については，「8.2.1　サンプル共通の作業（Baseサンプル）」を参照してください。

8.3.2　DAMサンプル固有の作業

DAMサンプル固有の準備手順について説明します。ここの記述では，次の条件でサンプルを使うものとします。

使うシェル：Cシェル

OpenTP1ホームディレクトリ：/usr/betran

(1)　アプリケーションプログラムを作成します

DAMサンプル用のサンプルプログラムを作成する手順を示します。サンプルプログラムは，UNIXのツールmakeコマンドを使います。サンプルでは，専用のmakefileをDAMサンプルのディレクトリに作成してあります。makeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1のセットアップについては，「8.3.3(1)　OpenTP1をセットアップします」を参照してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

(a)　トランザクション制御用オブジェクトファイルの作成

OpenTP1のコマンドtrnmkobjコマンドで，トランザクション制御用オブジェクトファイルを作成します。

サンプルで使うmakefile内では，トランザクション制御用オブジェクトファイルをdam_sw.oという名称で作成するようにしてあります。そのため，trnmkobjコマンドを実行して作成するオブジェクトファイル名は，dam_sw.oになるようにしてください。

オブジェクトファイルは，$DCDIR/spool/trnrmcmd/userobj/ディレクトリの下に作成されます。同じ名称のオブジェクトファイルがある場合は，事前に退避させておいてください。

コマンド入力例を次に示します。

%  trnmkobj  -o  dam_sw  -R  OpenTP1_DAM  <CR>

(b)　UAPの実行形式ファイルの作成

aplib/ディレクトリにあるc/またはcobol/ディレクトリをカレントディレクトリとして，makeコマンドを実行します。

C言語のUAPを作成するコマンド入力例を次に示します。

%  chdir  $DCDIR/examples/dam/aplib/c  <CR>
%  make   <CR>

このコマンドを実行すると，aplib/ディレクトリにUAPの実行形式ファイル（C言語）が作成されます。

(2)　システム定義を修正します

サンプルでは，システム定義の手間を省くために，システム定義の定義例を提供しています。ただし，一部の定義ファイルは，実際のOpenTP1ホームディレクトリを絶対パス名で指定する必要があります。

(a)　OpenTP1ホームディレクトリの定義を変更する手順

実際のOpenTP1ホームディレクトリに修正するときは，変更用のツールchconfコマンドを使います。このコマンドを実行と，定義ファイルにOpenTP1ホームディレクトリが$DCDIRとなっている部分をOpenTP1ホームディレクトリ（例えば，/usr/betran）に変更します。

chconfコマンドは，conf/ディレクトリに移動してから実行します。

コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/dam/conf  <CR>
%  chconf  <CR>

chconfコマンドを実行すると，定義ファイルの内容が変更されます。変更する定義ファイルと変更する内容を次の表に示します。変更される部分を太字で示します。

表8‒5　変更する定義ファイルと変更する内容（DAMサンプル）

変更する定義ファイル

変更する内容

env

putenv DCCONFPATH $DCDIR/examples/dam/conf

prc

putenv prcsvpath $DCDIR/examples/dam/aplib

sts

物理ファイル名：$DCDIR/examples/dam/betranfile/×××

sysjnl

物理ファイル名：$DCDIR/examples/dam/betranfile/×××

cdtrn

物理ファイル名：$DCDIR/examples/dam/betranfile/×××

このツール（chconfコマンド）を実行する前には，環境変数DCDIRにあらかじめOpenTP1ホームディレクトリを設定しておいてください。設定していないと正常に変更できません。

(b)　変更したOpenTP1ホームディレクトリを元に戻す方法

変更したOpenTP1ホームディレクトリを元に戻すときは，変更取り消し用のツールbkconfコマンドを使います。chconfコマンドで変更しようとした内容を，初期状態に戻します。

chconfコマンドでシステム定義を正常に変更できなかった場合は，すぐにbkconfコマンドを実行してください。

コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/dam/conf  <CR>
%  bkconf  <CR>

(3)　環境変数と定義ファイルを設定します

作成したサンプルUAPとサンプルのシステム定義で，OpenTP1システムを開始する手順について説明します。

(a)　環境変数DCCONFPATHの設定

環境変数DCCONFPATHに定義ファイルを格納しているディレクトリを設定します。この設定をすると，OpenTP1が定義ファイルの内容を認識できるようになります。

コマンド入力例を次に示します。

cshの場合

%  setenv  DCCONFPATH  $DCDIR/examples/dam/conf  <CR>

bashの場合

$  export  DCCONFPATH=$DCDIR/examples/dam/conf  <CR>

(b)　定義ファイルenvのコピー

定義ファイルのうち，envファイルだけは，$DCDIR/confからOpenTP1に読み込まれます。そのため，サンプルとして作成したenv定義ファイルを$DCDIR/confへ移動します。

$DCDIR/conf/ディレクトリにenv定義ファイルを作成している場合は，上書きされてしまうので，必要であれば退避しておいてください。

コマンド入力例を次に示します。

%  cp  $DCDIR/examples/dam/conf/env  $DCDIR/conf  <CR>

(c)　OpenTP1ファイルシステムの初期化

OpenTP1ファイルシステムを初期化します。DAMサンプル用のOpenTP1ファイルシステムの初期化は，dam_mkfsというシェルファイルを実行します。

コマンド入力例を次に示します。

%  dam_mkfs  <CR>

このシェルファイルを実行すると，$DCDIR/examples/dam/ディレクトリの下にbetranfileというファイルが生成され，この下にOpenTP1ファイルシステムが構築されます。

8.3.3　OpenTP1を使うための作業

システム定義を修正し終わったら，OpenTP1を使うための作業をします。

(1)　OpenTP1をセットアップします

OpenTP1をセットアップするときは，dcsetupコマンドを実行します。dcsetupコマンドは，/BeTRAN/bin/ディレクトリの下にあります。

コマンド入力例を次に示します。

%  /BeTRAN/bin/dcsetup  OpenTP1ホームディレクトリ名  <CR>

セットアップの作業は，スーパユーザが操作します。dcsetupコマンドは，絶対パス名で実行してください。dcsetupコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。

サンプルプログラムを作成するmakeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

(2)　OpenTP1システムとユーザサーバを起動します

作成したサンプルUAPとサンプルのシステム定義で，OpenTP1システムを開始する手順について説明します。

(a)　OpenTP1システムの起動

OpenTP1システムをdcstartコマンドで起動します。

コマンド入力例を次に示します。

%  dcstart <CR>

(b)　ユーザサーバ（UAP）の起動

dcsvstartコマンドで，作成したUAPを起動します。サーバUAP（SPP）を起動してから，クライアントUAP（SUP）を起動します。

コマンド入力例を次に示します。

%  dcsvstart -u damspp  <CR>

  damsppがオンライン状態になったことがメッセージログで出力されます。

%  dcsvstart -u damsup  <CR>

  damsupがオンライン状態になったことがメッセージログで出力されます。

  ユーザサーバ（UAP）の処理経過がメッセージログに出力されます。

サーバUAP（SPP）は，ユーザサービス構成定義でOpenTP1システムの起動時に自動的に起動することもできます。

(3)　OpenTP1ファイルシステムの内容一覧

OpenTP1ファイルシステム作成ツールdam_mkfsを実行すると，$DCDIR/examples/dam/betranfile/ディレクトリの下にOpenTP1ファイルシステムが作成されます。作成されるOpenTP1ファイルシステムの内容を次の表に示します。

表8‒6　OpenTP1ファイルシステムの内容一覧（DAMサンプル）

ファイル名

使う目的となるファイル

レコード長

レコード数

jnlf01

システムジャーナルファイル

4096バイト

100レコード

jnlf02

システムジャーナルファイル

4096バイト

100レコード

jnlf03

システムジャーナルファイル

4096バイト

100レコード

stsfil01

ステータスファイル

4608バイト

64レコード

stsfil02

ステータスファイル

4608バイト

64レコード

stsfil03

ステータスファイル

4608バイト

64レコード

stsfil04

ステータスファイル

4608バイト

64レコード

cpdf01

チェックポイントダンプファイル

4096バイト

100レコード

cpdf02

チェックポイントダンプファイル

4096バイト

100レコード

cpdf03

チェックポイントダンプファイル

4096バイト

100レコード

smplfile

DAMファイル

512バイト※

11ブロック

注※

DAMファイルの欄は，ブロック長を示します。

(4)　サンプルUAPの入れ替え

サンプルのUAPは，次に示す手順で入れ替えてください。

OpenTP1システムを停止します。

dcsetupコマンドに-dオプションを付けて実行して，いったんOpenTP1をOSから削除します。

「8.3　DAMサンプルの使い方」で示す手順で，使いたいサンプルのUAPを設定し直します。

UAPを実行します。

8.4　TAMサンプルの使い方

TAMサンプルを使う手順について説明します。サンプルを使う手順の概要を次の図に示します。

図8‒5　サンプルを使う手順の概要（TAMサンプル）

8.4.1　サンプル共通の作業（TAMサンプル）

次に示す手順は，OpenTP1の3種類のサンプルに共通する準備です。

環境変数DCDIRにOpenTP1ホームディレクトリを設定します

OpenTP1管理者のコマンドサーチパスにディレクトリを追加します

OpenTP1のサンプル一式をコピーします

上記の手順については，「8.2.1　サンプル共通の作業（Baseサンプル）」を参照してください。

8.4.2　TAMサンプル固有の作業

TAMサンプル固有の準備手順について説明します。ここの記述では，次の条件でサンプルを使うものとします。

使うシェル：Cシェル

OpenTP1ホームディレクトリ：/usr/betran

(1)　アプリケーションプログラムを作成します

TAMサンプル用のサンプルプログラムを作成する手順を示します。サンプルプログラムは，UNIXのツールmakeコマンドを使います。サンプルでは，専用のmakefileをTAMサンプルのディレクトリに作成してあります。makeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1のセットアップについては，「8.4.3(1)　OpenTP1をセットアップします」を参照してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

(a)　トランザクション制御用オブジェクトファイルの作成

OpenTP1のコマンドtrnmkobjコマンドで，トランザクション制御用オブジェクトファイルを作成します。

サンプルで使うmakefile内では，トランザクション制御用オブジェクトファイルをtam_sw.oという名称で作成するようにしてあります。そのため，trnmkobjコマンドを実行して作成するオブジェクトファイル名は，tam_sw.oになるようにしてください。

オブジェクトファイルは，$DCDIR/spool/trnrmcmd/userobj/ディレクトリの下に作成されます。同じ名称のオブジェクトファイルがある場合は，事前に退避させておいてください。

コマンド入力例を次に示します。

%  trnmkobj  -o  tam_sw  -R  OpenTP1_TAM  <CR>

(b)　UAPの実行形式ファイルの作成

aplib/ディレクトリにあるc/またはcobol/ディレクトリをカレントディレクトリとして，makeコマンドを実行します。C言語のUAPを作成するコマンド入力例を次に示します。

%  chdir  $DCDIR/examples/tam/aplib/c  <CR>
%  make  <CR>

このコマンドを実行すると，aplib/ディレクトリにUAPの実行形式ファイル（C言語）が作成されます。

(2)　システム定義を修正します

サンプルでは，システム定義の手間を省くために，システム定義の初期値を提供しています。ただし，一部の定義ファイルは，実際のOpenTP1ホームディレクトリを絶対パス名で指定する必要があります。

(a)　OpenTP1ホームディレクトリの定義を変更する手順

実際のOpenTP1ホームディレクトリに修正するときは，変更用のツールchconfコマンドを使います。このコマンドを実行することで，定義ファイルにOpenTP1ホームディレクトリが$DCDIRとなっている部分をOpenTP1ホームディレクトリ（例えば，/usr/betran）に変更します。

chconfコマンドは，サンプルで提供するconf/ディレクトリに移動してから実行します。コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/tam/conf  <CR>
%  chconf  <CR>

chconfコマンドを実行すると，定義ファイルの内容が変更されます。変更する定義ファイルと変更する内容を次の表に示します。変更される部分を太字で示します。

表8‒7　変更する定義ファイルと変更する内容（TAMサンプル）

変更する定義ファイル

変更する内容

env

putenv DCCONFPATH $DCDIR/examples/tam/conf

prc

putenv prcsvpath $DCDIR/examples/tam/aplib

sts

物理ファイル名：$DCDIR/examples/tam/betranfile/×××

sysjnl

物理ファイル名：$DCDIR/examples/tam/betranfile/×××

cdtrn

物理ファイル名：$DCDIR/examples/tam/betranfile/×××

このツール（chconfコマンド）を実行する前には，環境変数DCDIRにあらかじめOpenTP1ホームディレクトリを設定しておいてください。設定していないと正常に変更できません。

(b)　変更したOpenTP1ホームディレクトリを元に戻す方法

変更したOpenTP1ホームディレクトリを元に戻すときは，変更取り消し用のツールbkconfコマンドを使います。chconfコマンドで変更しようとした内容を，初期状態に戻します。

chconfコマンドでシステム定義を正常に変更できなかった場合は，すぐにbkconfコマンドを実行してください。

コマンド入力例を次に示します。

%  chdir  $DCDIR/examples/tam/conf  <CR>
%  bkconf  <CR>

(3)　環境変数と定義ファイルを設定します

作成したサンプルUAPとサンプルのシステム定義で，OpenTP1システムを開始する手順について説明します。

(a)　環境変数DCCONFPATHの設定

環境変数DCCONFPATHに定義ファイルを格納しているディレクトリを設定します。この設定をすることで，OpenTP1が定義ファイルの内容を認識できるようになります。

コマンド入力例を次に示します。

cshの場合

%  setenv  DCCONFPATH  $DCDIR/examples/tam/conf  <CR>

bashの場合

$  export  DCCONFPATH=$DCDIR/examples/tam/conf  <CR>

(b)　定義ファイルenvのコピー

定義ファイルのうち，envファイルだけは，$DCDIR/confからOpenTP1に読み込まれます。そのため，サンプルとして作成したenv定義ファイルを$DCDIR/confへ移動します。

$DCDIR/conf/ディレクトリにenv定義ファイルを作成している場合は，上書きされてしまうので，必要であれば退避しておいてください。

コマンド入力例を次に示します。

%  cp  $DCDIR/examples/tam/conf/env  $DCDIR/conf  <CR>

(c)　OpenTP1ファイルシステムの初期化

OpenTP1ファイルシステムを初期化します。TAMサンプル用のOpenTP1ファイルシステムの初期化は，tam_mkfsというシェルファイルを実行します。

コマンド入力例を次に示します。

%  tam_mkfs  <CR>

このシェルファイルを実行することで，$DCDIR/examples/tam/ディレクトリの下にbetranfileというファイルが生成され，この下にOpenTP1ファイルシステムが構築されます。

8.4.3　OpenTP1を使うための作業

システム定義を修正し終わったら，OpenTP1を使うための作業をします。

(1)　OpenTP1をセットアップします

OpenTP1をセットアップするときは，dcsetupコマンドを実行します。dcsetupコマンドは，/BeTRAN/bin/ディレクトリの下にあります。

コマンド入力例を次に示します。

%  /BeTRAN/bin/dcsetup  OpenTP1ホームディレクトリ名  <CR>

セットアップの作業は，スーパユーザが操作します。dcsetupコマンドは，絶対パス名で実行してください。dcsetupコマンドについては，マニュアル「OpenTP1 運用と操作」を参照してください。

サンプルプログラムを作成するmakeコマンドは，OpenTP1をセットアップしたあとに実行してください。OpenTP1をセットアップする前にmakeコマンドを実行するとコンパイルエラーで失敗します。

(2)　OpenTP1システムとユーザサーバを起動します

作成したサンプルUAPとサンプルのシステム定義で，OpenTP1システムを開始する手順について説明します。

(a)　OpenTP1システムの起動

OpenTP1システムをdcstartコマンドで起動します。コマンド入力例を次に示します。

%  dcstart  <CR>

(b)　ユーザサーバ（UAP）の起動

dcsvstartコマンドで，作成したUAPを起動します。サーバUAP（SPP）を起動してから，クライアントUAP（SUP）を起動します。コマンド入力例を次に示します。

%  dcsvstart -u tamspp  <CR>

  tamsppがオンライン状態になったことがメッセージログで出力されます。

%  dcsvstart -u tamsup  <CR>

  tamsupがオンライン状態になったことがメッセージログで出力されます。

  ユーザサーバ（UAP）の処理経過が出力されます。

サーバUAP（SPP）は，ユーザサービス構成定義でOpenTP1システムの起動時に自動的に起動することもできます。

(3)　OpenTP1ファイルシステムの内容一覧

OpenTP1ファイルシステム作成ツールtam_mkfsを実行すると，$DCDIR/examples/tam/betranfile/ディレクトリの下にOpenTP1ファイルシステムが作成されます。

作成されるOpenTP1ファイルシステムの内容を，次の表に示します。

表8‒8　OpenTP1ファイルシステムの内容一覧（TAMサンプル）

ファイル名

使う目的となるファイル

レコード長

レコード数

jnlf01

システムジャーナルファイル

4096バイト

50レコード

jnlf02

システムジャーナルファイル

4096バイト

50レコード

jnlf03

システムジャーナルファイル

4096バイト

50レコード

stsfil01

ステータスファイル

4608バイト

256レコード

stsfil02

ステータスファイル

4608バイト

256レコード

stsfil03

ステータスファイル

4608バイト

256レコード

stsfil04

ステータスファイル

4608バイト

256レコード

cpdf01

チェックポイントダンプファイル

4096バイト

100レコード

cpdf02

チェックポイントダンプファイル

4096バイト

100レコード

cpdf03

チェックポイントダンプファイル

4096バイト

100レコード

作成されるTAMファイルの仕様を，次の表に示します。

表8‒9　TAMサンプル用TAMファイルの仕様

ファイル名

tamexam1

使う目的となるファイル

TAMファイル

レコード長

40バイト（キー長を含む）

キー領域長

20バイト

キー開始位置

0バイト目（レコードの先頭）

最大レコード数

10レコード

テーブル形式

ツリー形式

TAMデータファイル名

$DCDIR/examples/tools/tamdata

(4)　サンプルUAPの入れ替え

サンプルのUAPは，次に示す手順で入れ替えてください。

OpenTP1システムを停止します。

dcsetupコマンドに-dオプションを付けて実行して，いったんOpenTP1をOSから削除します。

「8.4　TAMサンプルの使い方」で示す手順で，使いたいサンプルのUAPを設定し直します。

UAPを実行します。

8.5　サンプルプログラムの仕様

ここでは，次に示す3種類のサンプルで使うUAPの仕様について説明します。

Baseサンプル

DAMサンプル

TAMサンプル

説明するサンプルの仕様は，上記の3種類のサンプルで共通です。

8.5.1　サンプルで使うデータベースの内容

サンプルのUAPでは，構築した顧客情報のデータベースを，名前をキーにして個人情報を参照したり，販売額を更新したりします。

顧客情報データベースの形式を次の表に示します。

表8‒10　顧客情報データベースの形式

名前

性別

年齢

販売額

Tanaka

Male

25

200000

Saitoh

Female

22

1200000

Nakamura

Male

30

500000

Miyamoto

Male

19

800000

Suzuki

Female

20

950000

8.5.2　サンプルプログラムの処理の概要

サンプルプログラムの処理の概要について説明します。処理については，サンプルプログラムのソースファイルの内容を参照してください。

クライアントUAPは，「参照目的」の要求で，一人の個人情報をサーバのデータベースから取り出します。次に「更新目的」の要求をサーバに送って，販売額を書き替えます。最後に「参照目的」を要求して，更新されたことを確認します。

クライアントUAPからサーバUAPへサービスを要求するときは，メッセージログを出力して，動作を確認できるようにしています。「参照目的」の要求時には参照後に，「更新目的」の要求時には更新前にメッセージログを出力します。

サーバUAP側でも，参照と更新の各処理が完了すると，処理がうまくいったかどうかを知らせるメッセージログが出力されます。

クライアントUAP，サーバUAPのそれぞれの出力メッセージに"client"，または"server"の文字列が付けられるので，メッセージログがどちらのUAPから出力されたかがわかるようにしてあります。C言語の場合のクライアントUAPとサーバUAPの呼び出しの関係を図8-6に，COBOL言語の場合のクライアントUAPとサーバUAPの呼び出しの関係を図8-7に示します。

図8‒6　クライアントUAPとサーバUAPの呼び出しの関係（C言語）

図8‒7　クライアントUAPとサーバUAPの呼び出しの関係（COBOL言語）

8.5.3　サンプルプログラムのプログラム構造

クライアントUAPは，一つのプログラムから構成されます。サーバUAPは，複数のプログラムから構成されます。C言語のサンプルUAPとCOBOL言語のサンプルUAPでは，プログラムの名称が一部異なります。

(1)　C言語のプログラム構造

C言語の場合の，クライアントUAPとサーバUAPのプログラム構造を次の図に示します。

図8‒8　クライアントUAPとサーバUAPのプログラム構造（C言語）

(2)　COBOL言語のプログラム構造

COBOL言語の場合，サーバUAPのプログラムの構造で，プログラムを一つ追加しています。BaseサンプルのCOBOLのUAPのプログラム構造を次の図に示します。

図8‒9　クライアントUAPとサーバUAPのプログラム構造（COBOL言語）

8.5.4　サンプル別のプログラムの詳細

サンプル別で異なる仕様について説明します。

(1)　Baseサンプルのプログラム

Baseサンプルでは，データベース（DataBase）はユーザサーバのプロセスの内部に生成されて，プロセスが常駐している間だけ保持されます。トランザクションの開始と同期点処理は，サーバUAP側の更新処理で実行しています。

(2)　DAMサンプルのプログラム

次の3点を除いて，Baseサンプルと同じです。

COBOL言語の場合，サーバUAPのプログラム構造が，Baseサンプルと異なります。DAMサンプルのCOBOLのUAPのプログラム構造を次の図に示します。

図8‒10　クライアントUAPとサーバUAPのプログラム構造（COBOL言語DAMサンプル）

DAMサンプルは，データベース（DataBase）をオフラインプログラム（dam_mkfs）で作成しているので，ユーザサーバのプロセスが終了してもデータベースは残ります。

トランザクションの開始と同期点取得は，サーバUAP側の各処理（参照，または更新）で実行しています。

(3)　TAMサンプルのプログラム

次の3点を除いて，Baseサンプルプログラムと同じです。

COBOL言語の場合，サーバUAPのプログラム構造が，Baseサンプルと異なります。TAMサンプルのCOBOLのUAPのプログラム構造は，DAMサンプルと同じです。詳細は，図8-10を参照してください。

TAMサンプルは，データベース（DataBase）をオフラインプログラム（tam_mkfs）で作成しているので，ユーザサーバのプロセスが終了してもデータベースは残ります。

トランザクションの開始と同期点取得は，サーバUAP側の各処理（参照，または更新）で実行しています。

(4)　サンプル使用上の注意

サンプルを使用してOpenTP1を起動すると，KFCA00901-Wメッセージが出力されることがありますが，使用しないリソースマネジャに関するメッセージの場合は無視してください。

サンプルプログラムのmakefileではCコンパイラとして/bin/ccを明示的に指定しています。/bin/ccがない，または/bin/cc以外のCコンパイラを使用する場合は，makefile上で使用するCコンパイラを絶対パスで指定してから使用してください。

8.6　MCFサンプルの使い方

メッセージ制御機能（MCF）のサンプル（MCFサンプル）について説明します。MCFサンプルは，マニュアルに掲載している次の記述を，UNIXのテキストファイルとして使えるようにしたものです。

システム定義例

MHPのプログラムコーディング例（C言語，COBOL言語，DMLを使ったCOBOL言語）

MCFメイン関数例（ANSI C，C++の形式とK&R版 Cの形式）

8.6.1　MCFサンプルのディレクトリ構造

MCFサンプルは，MCFの基本部分と通信プロトコル対応部分に分けてあります。MCFサンプルのディレクトリ構造を次の図に示します。

図8‒11　MCFサンプルのディレクトリ構造

$DCDIR/examples/mcf/ディレクトリ下の各ディレクトリの内容を次に示します。

aplib/

サンプルのMHPが格納してあるディレクトリ

conf/

サンプルのシステム定義が格納してあるディレクトリ

psv/cmlib/

サンプルのMCFメイン関数が格納してあるディレクトリ

プロトコル/

通信プロトコル製品別のサンプルが格納してあるディレクトリ

プロトコル／ディレクトリの下にも，次に示すディレクトリが格納してあります。

サンプルのMHP，SPPが格納してあるディレクトリ

システム定義が格納されているディレクトリ

MCFメイン関数が格納されているディレクトリ

(1)　mcf/aplib/ディレクトリの内容

mcf/aplib/ディレクトリの下には，次に示すファイルが格納してあります。

c/

MHPのソースファイル（C言語）が格納されているディレクトリです。ここには，MHPのメイン関数（mhp.c）と，MHPのサービス関数（ap1.c）があります。

cobol/

MHPのソースファイル（COBOL言語）が格納されているディレクトリです。ここには，MHPのメインプログラム（mhp.cbl）と，MHPのサービスプログラム（ap.cbl）があります。

dml/

MHPのソースファイル（COBOL言語DML）が格納されているディレクトリです。ここには，MHPのサービスプログラム（ap.cbl）があります。

上記のプログラムの内容については，マニュアル「OpenTP1 プログラム作成リファレンス」の該当する言語編のコーディング例を参照してください。

(2)　conf/ディレクトリの内容

mcf/conf/ディレクトリの下には，次に示すファイルが格納してあります。

abc_mngr

MCFマネジャ定義のサンプルです。

abc_ua_c

MCF通信構成定義の共通定義のサンプルです。この定義は，OSAS/UAプロトコル用です。

abc_ua_d

MCF通信構成定義のプロトコル固有定義のサンプルです。この定義内容は，OSAS/UAプロトコル用です。

psvr_psvr_cmn

MCF通信構成定義の共通定義のサンプルです。この定義は，アプリケーション起動定義用です。

psvr_psvr_dta

MCF通信構成定義のアプリケーション起動定義のサンプルです。

abc_apli

MCFアプリケーション定義のサンプルです。

mcfu01

MCFシステムサービス情報定義のサンプルです。この定義は，MCF通信プロセス（OSAS/UA用）の内容です。

mcfu02

MCFシステムサービス情報定義のサンプルです。この定義は，アプリケーション通信プロセスの内容です。

上記の定義内容については，マニュアル「OpenTP1 システム定義」の定義例を参照してください。

(3)　psv/cmlib/ディレクトリの内容

mcf/psv/cmlib/ディレクトリの下には，次に示すディレクトリが格納してあります。

ansi/

アプリケーション起動プロセス用のMCFメイン関数（ANSI C，C++の形式）のサンプルです。

c/

アプリケーション起動プロセス用のMCFメイン関数（K&R版Cの形式）のサンプルです。

上記のMCFメイン関数の内容については，マニュアル「OpenTP1 運用と操作」の定義例を参照してください。MCF通信サービス用のMCFメイン関数については，mcf/プロトコル/cmlib/ディレクトリの下のファイルを参照してください。

(4)　プロトコル/ディレクトリについて

プロトコル/ディレクトリの下には，通信プロトコル対応製品別のサンプルが格納してあります。プロトコル/ディレクトリは，通信プロトコル対応製品によって名称が異なります。ディレクトリの名称と製品名の対応を次に示します。

OSASNIF：TP1/NET/OSAS-NIF

OSITP：TP1/NET/OSI-TP

SLUP2：TP1/NET/SLU-TypeP2

TCPIP：TP1/NET/TCP/IP

UDPIP：TP1/NET/UDP

UserAgent：TP1/NET/User Agent

XMAP3：TP1/NET/XMAP3

各ディレクトリの内容については，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編を参照してください。

8.6.2　MCFサンプルを使うときの注意

MCFサンプルを使うときの注意事項を次に示します。

MCFに関連する定義（ネットワークコミュニケーション定義）を使うときは，MCFサンプル内で一貫した定義になるようにしてください。システム定義の内容は，マニュアルに掲載しているものをそのまま使っているため，一部修正が必要な場合があります。また，TP1/Server Baseの定義（システムサービス定義）は，MCFサンプルのネットワークコミュニケーション定義に合わせて修正する必要があります。これは，Baseサンプルを使う場合も同様です。

プロトコル/ディレクトリの下のUAP（MHP，SPP）のサンプルを使う場合，コンパイル／リンケージ時にメイン関数（メインプログラム）が必要です。MHPの場合は，mcf/aplib/ディレクトリにあるメイン関数を修正して使ってください。SPPの場合は，メイン関数を新規で作成してください。

mcf/conf/ディレクトリの下にあるMCFアプリケーション定義（abc_apli）は，作成するMHPに合わせた修正が必要です。さらに，システムサービス定義（ユーザサービス定義など）も，新規で作成する必要があります。

MCFメイン関数は，次のサンプルを使ってください。

MCF通信サービスのMCFメイン関数

/mcf/プロトコル/cmlib/ディレクトリの下のファイル

アプリケーション起動サービスのMCFメイン関数

/mcf/psv/cmlib/ディレクトリの下のファイル

8.7　マルチOpenTP1のコマンドを振り分けるサンプル

マルチOpenTP1のノードにrshなどを使ってほかのノードからコマンドを実行する場合，どちらのOpenTP1でコマンドが実行されるかわかりません。そのため，ノード名を指定してコマンドを実行する必要があります。このようなコマンドを実行するために，ノード名を指定してコマンドを実行するコマンド（シェルファイル）がサンプルに格納してあります。このコマンドは，Baseサンプルのtools/ディレクトリの下に，delvcmdという名称で格納してあります。

ただし，Windows版TP1/Server BaseまたはTP1/LiNKでは，dcmakeconコマンドでコマンドプロンプトを作成し，その中でコマンドを実行してください。dcmakeconコマンドについては，マニュアル「OpenTP1 使用の手引 Windows(R)編」または「TP1/LiNK 使用の手引」を参照してください。

8.7.1　delvcmdコマンドの使い方

delvcmdコマンドは，次の形式で実行します。

delvcmd  -w  ノード名〔，ノード名〕… コマンド名

ノード名には，同じマシン内のノード識別子を指定します。ノード名は，複数指定できます。複数指定するときは，ノード名とノード名をコンマ（，）で区切ります。

コマンド入力例を次に示します。これは，ノード"nd01"とノード"nd02"にprclsコマンドを実行する例です。入力形式は次に示すどちらでもかまいません。

%  delvcmd  "prcls"  -w  nd01,nd02  <CR>

%  delvcmd  -w  nd01,nd02  "prcls"  <CR>

このコマンドを使う前に，コマンド内にノードごとの$DCDIR，$DCCONFPATH，$SHLIB_PATH，$PATHを，絶対パス名で指定しておいてください。

引数として指定するコマンドは，アポストロフィ（’）と引用符（"）のどちらかで囲んでください。ただし，次に示すコマンドについては制限があります。

MCFのコマンドの場合はアポストロフィ（’）で囲む。

TP1/Multiのコマンドの場合は引用符（"）で囲む。

8.7.2　コマンド引数に指定する値の制限

delvcmdコマンドの引数には，アスタリスク（*）は使えません。アスタリスクを使ってコマンド引数を一括指定すると，delvcmdコマンドが正常に実行できない場合があります。

delvcmdコマンドに指定するコマンド名には，パイプやリダイレクションは使えません。delvcmdコマンドの実行結果はパイプまたはリダイレクションできます。コマンド入力例を次に示します。

%  delvcmd  "prcls"  -w  nd01, nd02  >  file  <CR>

8.7.3　delvcmdコマンドで実行できないコマンド

OpenTP1システムに設定されているアクセス権限によっては，delvcmdコマンドで実行できないコマンドがあります。この場合，delvcmdコマンドを実行する利用者が，対象となるノードのOpenTP1管理者と同じ利用者名称である必要があります。

8.8　COBOL言語用テンプレート

UAPをCOBOL言語で作成するときに，データ部（DATA DIVISION）のコーディングの負担を軽くするため，COBOL言語用テンプレートを格納してあります。

COBOL言語用テンプレートは，/BeTRAN/examples/COBOL/ディレクトリの下にあります。

8.8.1　COBOL言語用テンプレートのファイル

COBOL言語用テンプレートは，OpenTP1のシステムサービス別に分けてあります。テンプレートのファイル名は，DC×××.cbl（×××は，COBOL-UAP作成用プログラムの下3文字）です。COBOL言語用テンプレートのファイルを次に示します。

DCADM.cbl：システム運用の管理（CBLDCADM）

DCDAM.cbl：DAMファイルサービス（CBLDCDAM）

DCDMB.cbl：DAMファイルサービス（CBLDCDMB）

DCIST.cbl：ISTサービス（CBLDCIST）

DCJNL.cbl：ユーザジャーナルの出力（CBLDCJNL）

DCJUP.cbl：ジャーナルデータの編集（CBLDCJUP）

DCLCK.cbl：資源の排他制御（CBLDCLCK）

DCLOG.cbl：メッセージログの出力（CBLDCLOG）

DCMCF.cbl：メッセージ送受信（CBLDCMCF）

DCPRF.cbl：性能検証用トレース（CBLDCPRF）

DCRAP.cbl：リモートAPI機能（CBLDCRAP）

DCRPC.cbl：リモートプロシジャコール（CBLDCRPC）

DCRSV.cbl：リモートプロシジャコール（CBLDCRSV）

DCTAM.cbl：TAMファイルサービス（CBLDCTAM）

DCTRN.cbl：トランザクション制御（CBLDCTRN）

DCUTO.cbl：オンラインテスタの管理（CBLDCUTO）

DCXAT.cbl：アソシエーションの操作（CBLDCXAT）

8.8.2　COBOL言語用テンプレートの使い方

COBOL言語用テンプレートを使うときは，次に示す値をコーディングするUAPの処理に合わせたものに修正する必要があります。

データ領域の長さ（ただし，一部のデータだけ）

各データ領域へ代入する値

データ領域に設定する値については，マニュアル「OpenTP1 プログラム作成リファレンス COBOL言語編」の各機能の文法に関する記述を参照してください。

COBOL言語用テンプレートの使い方には，次に示す2とおりがあります。

テキストエディタの呼び出し機能を使う方法

COBOL言語のCOPY文を使う方法

(1)　テキストエディタの呼び出し機能を使う方法

次の手順でテンプレートを使います。

/BeTRAN/examples/COBOL/ディレクトリから，使う機能のテンプレートを選びます。

テキストエディタの呼び出し機能を使って，DATA DIVISION部分を切り取って，UAPのソースプログラムに貼り付けます。

貼り付けた部分を，コーディングの処理に合ったデータ領域に修正します。

(2)　COBOL言語のCOPY文を使う方法

次の手順でテンプレートを使います。

/BeTRAN/examples/COBOL/ディレクトリから，使う機能のテンプレートを選びます。

UAPのソースプログラムから，テンプレートのファイル名でCOPY宣言します。このとき，COPY文に指定するファイル名は，テンプレートのファイル名から「.cbl」を除いた名称を使います。

テンプレートのファイルを，COPY文で参照できるディレクトリに置きます。この方法は，使うCOBOL言語の処理系に従ってください（ファイルのコピー，または環境変数の設定など）。

テンプレートのファイルを，コーディングの処理に合ったデータ領域に修正します。

(3)　COBOL言語用テンプレートを使うときの注意

UAPの処理に合わせて変更するデータ領域では，PICTURE句の長さを（n）と宣言しています。この部分を修正してから使ってください。修正しないままコンパイルすると，エラーになります。

次に示すCOBOL言語用テンプレートは，該当する製品が組み込まれていることが前提になります。

DCDAM.cbl，DCDMB.cbl：DAMファイルサービス（CBLDCDAM，CBLDCDMB）

DCTAM.cbl：TAMファイルサービス（CBLDCTAM）

DCMCF.cbl：メッセージ送受信（CBLDCMCF）

DCUTO.cbl：オンラインテスタの管理（CBLDCUTO）

DCIST.cbl：ISTサービス（CBLDCIST）

メッセージ送受信のテンプレート（DCMCF.cbl）は，OpenTP1で使えるすべてのMCF関連の情報が入っています。そのため，通信プロトコル対応製品によっては使えないCOBOL-UAP作成用プログラムのテンプレートがあります。また，データ領域に設定する値も，通信プロトコル対応製品別で異なります。DCMCF.cblを使う場合は，マニュアル「OpenTP1 プロトコル」の該当するプロトコル編に掲載しているCOBOL言語の文法を参照して，適切な形式に変更してから使ってください。

UAPの処理に合わせて変更するテンプレートを使う場合は，元のディレクトリからコピーして使うことをお勧めします。

8.9　サンプルシナリオテンプレートの使い方

OpenTP1ではスケールアウトのシナリオテンプレートを提供しています。このサンプルでは，スケールアウトのシナリオで使用するOpenTP1設定用スクリプトファイルを利用できます。このサンプルを使用するには，JP1シナリオ連携の前提となるJP1製品（JP1/AJS，JP1/AJS2 - Scenario Operation，JP1/Base）が必要です。サンプルシナリオテンプレートの詳細については，マニュアル「OpenTP1 運用と操作」の説明を参照してください。

8.10　リアルタイム取得項目定義テンプレートの使い方

OpenTP1では，リアルタイム統計情報サービスで使用するテンプレートとして，各種のリアルタイム取得項目定義ファイルを提供しています。これらのファイルはすべて，インストールディレクトリ/rts_template/examples/conf/に格納されます。リアルタイム取得項目定義ファイルは，$DCCONFPATH/直下にコピーして使用します。

リアルタイム取得項目定義ファイルのファイル名と内容を次の表に示します。

表8‒11　リアルタイム取得項目定義ファイルのファイル名と内容

ファイル名

内容

base_itm

BASE用のリアルタイム取得項目定義ファイル

dam_itm

DAM用のリアルタイム取得項目定義ファイル

tam_itm

TAM用のリアルタイム取得項目定義ファイル

all_itm

すべての統計情報を取得するリアルタイム取得項目定義ファイル

none_itm

すべての統計情報を取得しないリアルタイム取得項目定義ファイル

mcfs_itm

MCF用のリアルタイム取得項目定義ファイル（システム全体，サーバ，サービス単位に取得する項目）

mcfl_itm

MCF用のリアルタイム取得項目定義ファイル（論理端末単位に取得する項目）

mcfg_itm

MCF用のリアルタイム取得項目定義ファイル（サービスグループ単位に取得する項目）

リアルタイム取得項目定義の指定方法については，マニュアル「OpenTP1 システム定義」を参照してください。

付録

付録A　未決着トランザクション情報の出力形式

OpenTP1の全面回復時に，トランザクションサービス定義のtrn_tran_recovery_listオペランドにYと定義してあれば，未決着トランザクション情報をトランザクションサービスのノードにあるディレクトリに出力できます。

付録A.1　未決着トランザクション情報が出力されるディレクトリとファイル名

未決着トランザクション情報が出力されるディレクトリとファイル名を次に示します。

出力先ディレクトリは，トランザクションサービスが存在するノードのディレクトリ「$DCDIR/spool/dctrninf/」に出力されます。

トランザクションサービスの全面回復が発生するたびに，毎回一つのファイルとして出力されます。ファイル名は「rl＋トランザクションサービスの開始時間（一意の8けたの16進数）」となります。

このファイル名は，未決着トランザクション情報を出力したことを知らせるメッセージログに表示されます。

不要になった未決着トランザクション情報ファイルは，削除してください。削除する方法を次に示します。

コマンドで削除する方法

trndlinfコマンドを実行します。

OpenTP1の開始時に，前回までのオンラインで作成した情報を削除する方法

トランザクションサービス定義のtrn_recovery_list_removeオペランドとtrn_recovery_list_remove_levelオペランドに，削除する条件を指定しておきます。

付録A.2　未決着トランザクション情報の出力内容

未決着トランザクション情報として，次の項目が出力されます。

OpenTP1システムノードID

OpenTP1のシステムノードID。

グローバルトランザクション番号

グローバルトランザクションを管理するためにシステムで一意に付けた番号。

トランザクションブランチ番号

トランザクションブランチを管理するためにシステムで一意に付けた番号。

トランザクション第1状態

トランザクションブランチの処理状態。

トランザクション第2状態

トランザクションブランチのプロセスに関する状態。

トランザクション第3状態

トランザクションブランチの通信状態。

プロセスID

トランザクションブランチが動作しているプロセスのプロセスID。

サーバ名

トランザクションブランチを起動しているサーバの名称。

サービス名

トランザクションブランチを起動しているサービスの名称。

トランザクション記述子

同一トランザクショングローバル識別子を持つトランザクションブランチを区別するためのインデクス番号。

ブランチ記述子

一つのトランザクションブランチから分岐したトランザクションブランチを区別するためのインデクス番号。ルートトランザクションブランチの場合は「**********」が表示されます。

親トランザクション記述子

該当するトランザクションブランチを生成したトランザクションのトランザクション記述子。ルートトランザクションブランチの場合は「**********」が表示されます。

付録A.3　未決着トランザクション情報の出力形式

未決着トランザクション情報の出力形式と出力例を図A-1と図A-2に示します。

図A‒1　未決着トランザクション情報の出力形式

図A‒2　未決着トランザクション情報の出力例

付録B　デッドロック情報の出力形式

複数のUAP間でデッドロックが起こった場合，ロックサービス定義のlck_deadlock_infoオペランドにYと指定してあれば，デッドロック情報をロックサービスのノードにあるディレクトリに出力します。デッドロック情報を出力するのは次の場合です。

ロックサービスがデッドロックを検知した場合（デッドロック情報）

排他解除待ちで，タイムアウトになった場合（タイムアウト情報）

付録B.1　デッドロック情報が出力されるディレクトリとファイル名

デッドロック情報は，次に示す形式で出力されます。

デッドロック情報の出力先ディレクトリは，デッドロックまたはタイムアウトを検知したロックサービスが存在するノードのディレクトリ「$DCDIR/spool/dclckinf/」に出力されます。

デッドロック情報が発生するたびに，毎回一つのファイルとして出力されます。

ファイル名は，デッドロックまたはタイムアウトが起こった日付と時刻がファイル名になります。ファイル名の長さは日付が1けたか2けたかによって異なります。

（例）

10月3日7時41分00秒のとき…Oct3074100

10月10日15時5分27秒のとき…Oct10150527

このファイル名は，デッドロックが起こったことを知らせるメッセージログに表示されます。不要となったファイルは削除してください。

付録B.2　デッドロック情報の出力形式

デッドロックを検知したときのデッドロック情報の出力形式と出力例を図B-1と図B-2に示します。

図B‒1　デッドロック情報の出力形式

図B‒2　デッドロック情報の出力例

付録B.3　タイムアウト情報の出力形式

タイムアウトを検知したときのタイムアウト情報の出力形式と出力例を図B-3と図B-4に示します。

図B‒3　タイムアウト情報の出力形式

図B‒4　タイムアウト情報の出力例

付録B.4　TP1/FS/Table Accessを使用した場合の出力形式

TP1/FS/Table Accessを使用していて，その資源でデッドロック・タイムアウトが発生した場合は，テーブル名やキー値などの情報も出力されます。

デッドロックを検知したときのデッドロック情報の出力例を次の図に示します。

図B‒5　TAM資源のデッドロック情報の出力例

付録C　マルチスケジューラ機能の検討が必要なシステム構成例

システムの大規模化，マシンやネットワークの高性能化などに伴って，従来のスケジューラだけでは効率良くスケジューリングできないことがあります。ここでは，マルチスケジューラ機能の検討が必要なシステム構成例とその解決例について説明します。

付録C.1　スケジューラ機能の処理概要

スケジューラでは，クライアントUAPから他ノードのキュー受信型サーバ（スケジュールを使うSPP）にサービスを要求した場合，要求先サーバが存在するノードのスケジューラデーモンが，いったんサービス要求メッセージを受信して，該当するキュー受信サーバのスケジュールキューに格納します。

スケジューラデーモンは，クライアントUAPからのサービス要求メッセージを受信する受信スレッド（1スレッド）と，サービス要求をスケジュールへ格納する処理スレッド（最大64スレッド）で構成されています。

スケジューラ機能の処理概要を次の図に示します。

図C‒1　スケジューラ機能の処理概要

スケジューラデーモンの受信スレッドは，クライアントUAPからのサービス要求メッセージのうち，一度に受信できるメッセージ長を32キロバイトまでとしています。32キロバイトを超えたサービス要求メッセージの場合は，メッセージを分割して送受信することによって，スケジューラデーモンが1クライアントUAPのメッセージ受信処理に占有されないようにしています。

サービス要求メッセージの処理概要を次の図に示します。

図C‒2　サービス要求メッセージの処理概要

この図に示すように，スケジューラは，クライアントUAPからのサービス要求メッセージをスケジューリングします。

付録C.2　スケジューラが原因となるおそれのあるシステム構成例

システムの大規模化，マシンやネットワークの高性能化などに伴って，従来のスケジューラデーモンだけでは効率良くスケジューリングできない場合があります。スケジューラが原因となるおそれのあるシステム構成例について次に示します。

(1)　ソケットディスクリプタが不足するシステム

1スケジューラデーモンに接続するクライアントUAP数が増加すると，スケジューラデーモンが利用するソケットディスクリプタ数に，余裕を持った値を指定できないことがあります。スケジューラデーモンでソケットディスクリプタが不足すると，新たなソケットディスクリプタを確保するために接続済みのコネクションに対して，切断要求および切断処理が発生します。このコネクション切断処理を行うためにシステムにかかる負荷によって，スケジューラデーモンのスケジューリング性能が低下する場合があります。

ソケットディスクリプタが不足するシステム例を次の図に示します。

図C‒3　ソケットディスクリプタが不足するシステム例

(2)　connectシステムコールがエラーになるシステム

OpenTP1では通信プロトコルにTCP/IPを利用しているため，クライアントUAPからのコネクション確立要求（connectシステムコール）は，acceptシステムコールによって取り出されるまでlistenシステムコールの待ちキューとして保留されます。

コネクション確立要求を保留する待ちキューの数は，OSによって異なります。しかし，クライアントUAPからの要求が集中した場合，キューとして保留できる数を超えてコネクション確立要求が発生することがあります。

待ちキューとして保留できないコネクション確立要求が発生すると，CUP（TP1/Client）の場合はメッセージKFCA02449-Eを，SUPおよびSPP（TP1/Server Base）の場合はメッセージKFCA00327-Wを出力します。そしてこのサービス要求は通信障害またはOpenTP1未起動として扱われる場合があります。

connectシステムコールがエラーになるシステム例を次の図に示します。

図C‒4　connectシステムコールがエラーになるシステム例

(3)　回線速度が異なるネットワークを混在して利用しているシステム

スケジューラデーモンの受信スレッドは，特定のクライアントUAPのサービス要求メッセージを受信している間は，ほかのクライアントUAPのサービス要求メッセージを受信できません（ただし，サービス要求メッセージが32キロバイトを超える場合は分割して送受信されます）。

このため，回線速度が遅いネットワークに接続しているクライアントUAPのメッセージ受信処理によって，回線速度が速いネットワークに接続しているクライアントUAPからのメッセージ受信処理が遅延して，回線速度が速いネットワークの性能を有効に利用できない場合があります。

回線速度が異なるネットワークを混在して利用しているシステム例を次の図に示します。ここでは，回線速度が異なる二つの回線を比較した場合の例を挙げています。2倍の回線速度差がある回線を比較すると，受信処理にも回線速度と同じ2倍の時間差が出ることを示しています。

図C‒5　回線速度が異なるネットワークを混在して利用しているシステム例

(4)　サービス要求メッセージが途切れるシステム

クライアントUAPが強制終了するなどの理由によって，スケジューラデーモンへのサービス要求メッセージの送信処理が途切れると，受信スレッドのメッセージ受信処理がタイムアウトするまでスケジューリングが滞る場合があります。

サービス要求メッセージが途切れるシステム例を次の図に示します。

図C‒6　サービス要求メッセージが途切れるシステム例

(5)　処理スレッドが一時的に不足するシステム

クライアントUAPからのサービス要求メッセージが極端に集中して，スケジューラデーモンの処理能力を超えてしまうと，一時的に処理スレッドが不足することがあります。

処理スレッド不足が発生すると，メッセージKFCA00356-Wを出力して，一時的にサービス要求が通信障害やタイムアウトとして扱われる場合があります。

メッセージKFCA00356-Wは，システム共通定義のrpc_server_busy_countによって出力するタイミングを指定します。詳細は，マニュアル「OpenTP1 システム定義」を参照してください。

また，scdlsコマンドの-pオプションによって，スケジューラデーモンごとの処理スレッドの利用状況を表示できます。

処理スレッドが一時的に不足するシステム例を次の図に示します。

図C‒7　処理スレッドが一時的に不足するシステム例

付録C.3　マルチスケジューラ機能を使用したシステム構成例

マルチスケジューラ機能を使用すると，スケジューラが原因となるおそれのある問題を解決できます。ここでは，マルチスケジューラ機能を使用したシステム構成について説明します。

(1)　ソケットディスクリプタの不足を解決するシステム構成

スケジューラデーモンに接続するクライアントUAPを分散することで，1スケジューラデーモンが利用するソケットディスクリプタ数を少なくできます。

ソケットディスクリプタの不足を解決するシステム構成例を次の図に示します。

図C‒8　ソケットディスクリプタの不足を解決するシステム構成例

(2)　connectシステムコールのエラーを解決するシステム構成

スケジューラデーモンに接続するクライアントUAPを分散することによって，listenシステムコールの待ちキューとして保留されるコネクション確立要求数を少なくできます。

connectシステムコールのエラーを解決するシステム構成例を次の図に示します。

図C‒9　connectシステムコールのエラーを解決するシステム構成例

(3)　回線速度が速いネットワークを有効利用できるシステム（回線速度が異なるネットワークを混在して利用している場合）

回線速度が速いネットワークのクライアントUAPを処理するスケジューラデーモンと，回線速度が遅いネットワークのクライアントUAPを処理するスケジューラデーモンを分けることで，回線速度が速いネットワークを有効に利用できます。

回線速度が速いネットワークを有効利用できるシステム例を次の図に示します。

図C‒10　回線速度が速いネットワークを有効利用できるシステム例

(4)　サービス要求メッセージが途切れないシステム

マルチスケジューラ機能を用いて，メッセージ受信処理が滞るスケジューラデーモンを局所化すると，ほかのサービス要求メッセージを滞らせることなくスケジューリングできます。

サービス要求メッセージが途切れないシステム例を次の図に示します。

図C‒11　サービス要求メッセージが途切れないシステム例

(5)　同時実行可能な処理スレッド数を増やしたシステム

マルチスケジューラ機能を用いて，同時に実行できる処理スレッドの数を増やすことができます。これによって，処理スレッド不足による一時的な通信障害やタイムアウトを回避できます。

同時実行可能な処理スレッド数を増やしたシステム例を次の図に示します。

図C‒12　同時実行可能な処理スレッド数を増やしたシステム例

付録C.4　注意事項

マルチスケジューラ機能はTP1/Extension 1をインストールしていることが前提です。TP1/Extension 1をインストールしていない場合の動作は保証されません。

マルチスケジューラ機能の詳細は，マニュアル「OpenTP1 システム定義」または「OpenTP1 クライアント使用の手引 TP1/Client/W，TP1/Client/P編」を参照してください。

マルチスケジューラ機能を適用する場合には，システム定義の変更に加えて，スケジューラデーモンの増加に伴うカーネルパラメータの変更が必要となる場合があります。

OpenTP1システム内の同一サービスグループに，マルチスケジューラ機能を使用しているユーザサーバと，マルチスケジューラ機能を使用していないユーザサーバが混在する場合，次のことに注意してください。

マルチスケジューラ機能を使用したサービス要求は，マルチスケジューラ機能を使用しているユーザサーバに優先して負荷分散されます。

マルチスケジューラ機能を使用したサービス要求は，マルチスケジューラ機能を使用しているユーザサーバが高負荷状態でも，マルチスケジューラ機能を使用していないユーザサーバには負荷分散されません。マルチスケジューラ機能を使用しているユーザサーバが高負荷状態の場合に，マルチスケジューラ機能を使用していないユーザサーバに負荷分散するには，スケジュールサービス定義のscdmulti定義コマンドに-tオプションを指定してください。scdmulti定義コマンドの詳細については，マニュアル「OpenTP1 システム定義」のスケジュールサービス定義を参照してください。

索引

記号

$DCDIR/aplib/ディレクトリ[1]

数字

1相最適化[1]、[2]

2相コミット[1]

A

ANSI C[1]、[2]

ans型[1]

APIと運用コマンドの機能差異（MCF通信サービスに関する運用）[1]

APIと運用コマンドの機能差異（アプリケーションに関する運用）[1]

APIと運用コマンドの機能差異（コネクションの確立と解放）[1]

APIと運用コマンドの機能差異（コネクションの確立要求の受付開始と終了）[1]

APIと運用コマンドの機能差異（論理端末の閉塞と閉塞解除）[1]

atomic_update[1]

auto_restart[1]

B

balance_count[1]、[2]

Baseサンプル[1]、[2]

C

C++言語[1]

C++言語の仕様[1]

CBLDCADM('COMMAND ')[1]

CBLDCADM('COMPLETE')[1]、[2]

CBLDCADM('STATUS ')[1]

CBLDCDAM('CLOS')[1]

CBLDCDAM('END ')[1]

CBLDCDAM('HOLD')[1]

CBLDCDAM('OPEN')[1]

CBLDCDAM('READ')[1]

CBLDCDAM('REWT')[1]

CBLDCDAM('RLES')[1]

CBLDCDAM('STAT')[1]

CBLDCDAM('STRT')[1]

CBLDCDAM('WRIT')[1]

CBLDCDMB('BSEK')[1]

CBLDCDMB('CLOS')[1]

CBLDCDMB('CRAT')[1]

CBLDCDMB('DGET')[1]

CBLDCDMB('DPUT')[1]

CBLDCDMB('GET ')[1]

CBLDCDMB('OPEN')[1]

CBLDCDMB('PUT ')[1]

CBLDCIST('CLOS')[1]

CBLDCIST('OPEN')[1]

CBLDCIST('READ')[1]

CBLDCIST('WRIT')[1]

CBLDCJNL('UJPUT ')[1]

CBLDCJUP('CLOSERPT')[1]

CBLDCJUP('OPENRPT ')[1]

CBLDCJUP('RDGETRPT')[1]

CBLDCLCK('GET ')[1]

CBLDCLCK('RELALL ')[1]

CBLDCLCK('RELNAME ')[1]

CBLDCLOG('PRINT ')[1]

CBLDCMCF('ADLTAP ')[1]

CBLDCMCF('CLOSE ')[1]、[2]

CBLDCMCF('COMMIT ')[1]

CBLDCMCF('CONTEND ')[1]、[2]

CBLDCMCF('EXECAP ')[1]

CBLDCMCF('MAINLOOP')[1]、[2]

CBLDCMCF('OPEN ')[1]、[2]

CBLDCMCF('RECEIVE ')[1]、[2]

CBLDCMCF('RECVSYNC')[1]、[2]

CBLDCMCF('REPLY ')[1]、[2]

CBLDCMCF('RESEND ')[1]

CBLDCMCF('ROLLBACK')[1]

CBLDCMCF('SENDRECV')[1]、[2]

CBLDCMCF('SENDSYNC')[1]、[2]

CBLDCMCF('SEND ')[1]、[2]

CBLDCMCF('TACTCN ')[1]

CBLDCMCF('TACTLE ')[1]

CBLDCMCF('TDCTCN ')[1]

CBLDCMCF('TDCTLE ')[1]

CBLDCMCF('TDLQLE ')[1]

CBLDCMCF('TEMPGET ')[1]

CBLDCMCF('TEMPPUT ')[1]

CBLDCMCF('TIMERCAN')[1]

CBLDCMCF('TIMERSET')[1]

CBLDCMCF('TLSCN ')[1]

CBLDCMCF('TLSCOM ')[1]

CBLDCMCF('TLSLE ')[1]

CBLDCMCF('TLSLN ')[1]

CBLDCMCF('TOFLN ')[1]

CBLDCMCF('TONLN ')[1]

CBLDCPRF('PRFGETN ')[1]

CBLDCPRF('PRFPUT ')[1]

CBLDCRAP('CONNECT ')[1]

CBLDCRAP('DISCNCT ')[1]

CBLDCRPC('CALL ')[1]

CBLDCRPC('CLTSEND ')[1]

CBLDCRPC('DISCARDF')[1]

CBLDCRPC('DISCARDS' )[1]

CBLDCRPC('GETCLADR')[1]

CBLDCRPC('GETERDES')[1]

CBLDCRPC('GETSVPRI')[1]

CBLDCRPC('GETWATCH')[1]

CBLDCRPC('OPEN ')[1]、[2]、[3]

CBLDCRPC('POLLANYR')[1]

CBLDCRPC('SETSVPRI')[1]

CBLDCRPC('SETWATCH')[1]

CBLDCRPC('SVRETRY ')[1]

CBLDCRSV('MAINLOOP')[1]、[2]、[3]

CBLDCRTS('RTSPUT ')[1]

CBLDCTAM('ERS ')('ERSR')('BRS ')('BRSR')[1]

CBLDCTAM('FxxR')('FxxU')('VxxR')('VxxU')[1]

CBLDCTAM('GST ')[1]

CBLDCTAM('INFO')[1]

CBLDCTAM('MFY ')('MFYS')('STR ')('WFY ')('WFYS')('YTR ')[1]、[2]

CBLDCTRN('BEGIN ')[1]

CBLDCTRN('C-COMMIT')[1]

CBLDCTRN('C-ROLL ')[1]

CBLDCTRN('INFO ')[1]

CBLDCTRN('RMSELECT')[1]

CBLDCTRN('U-COMMIT')[1]

CBLDCTRN('U-ROLL ')[1]

CBLDCUTO('T-STATUS')[1]

CBLDCXAT('CONNECT ')[1]

CCLSEVT[1]、[2]

CERREVT[1]、[2]

COBOL2002[1]

COBOL85[1]

COBOL言語[1]

COBOL言語でコーディングする場合[1]

COBOL言語でコーディングする場合の概要[1]

COBOL言語用テンプレート[1]、[2]

COBOL-UAP作成用プログラム[1]

cont型[1]

COPNEVT[1]、[2]

CUP[1]

CUPへの一方通知[1]

C言語[1]

C言語でコーディングする場合の概要[1]

C言語またはC++言語でコーディングする場合[1]

D

damloadコマンド[1]

DAMサービスとTAMサービスとの互換[1]

DAMサンプル[1]、[2]

DAMファイル[1]

DAMファイルサービス[1]、[2]

DAMファイルにアクセスするときの名称[1]、[2]

DAMファイルの構成[1]

DAMファイルの状態の参照[1]

DAMファイルの排他制御[1]

dc_adm_call_command関数[1]

dc_adm_complete関数[1]、[2]

dc_adm_get_nd_status_begin関数[1]

dc_adm_get_nd_status_done関数[1]

dc_adm_get_nd_status_next関数[1]

dc_adm_get_nd_status関数[1]

dc_adm_get_node_id関数[1]

dc_adm_get_nodeconf_begin関数[1]

dc_adm_get_nodeconf_done関数[1]

dc_adm_get_nodeconf_next関数[1]

dc_adm_get_sv_status_begin関数[1]

dc_adm_get_sv_status_done関数[1]

dc_adm_get_sv_status_next関数[1]

dc_adm_get_sv_status関数[1]

dc_adm_status関数[1]

dc_clt_accept_notification関数[1]

dc_clt_chained_accept_notification関数[1]

dc_dam_bseek関数[1]、[2]

dc_dam_close関数[1]

dc_dam_create関数[1]

dc_dam_dget関数[1]、[2]

dc_dam_dput関数[1]

dc_dam_end関数[1]

dc_dam_get関数[1]、[2]

dc_dam_hold関数[1]

dc_dam_iclose関数[1]、[2]

dc_dam_iopen関数[1]

dc_dam_open関数[1]

dc_dam_put関数[1]、[2]

dc_dam_read関数[1]、[2]

dc_dam_release関数[1]

dc_dam_rewrite関数[1]

dc_dam_start関数[1]

dc_dam_status関数[1]

dc_dam_write関数[1]、[2]

dc_ist_close関数[1]

dc_ist_open関数[1]

dc_ist_read関数[1]

dc_ist_write関数[1]

dc_jnl_ujput関数[1]

dc_lck_get関数[1]、[2]

dc_lck_release_all関数[1]、[2]

dc_lck_release_byname関数[1]、[2]

dc_log_notify_close関数[1]

dc_log_notify_open関数[1]

dc_log_notify_receive関数[1]

dc_log_notify_send関数[1]

dc_logprint関数[1]

dc_mcf_adltap関数[1]

dc_mcf_close関数[1]

dc_mcf_commit関数[1]

dc_mcf_contend関数[1]、[2]

dc_mcf_execap関数[1]

dc_mcf_mainloop関数[1]、[2]

dc_mcf_open関数[1]

dc_mcf_receive関数[1]、[2]、[3]、[4]、[5]

dc_mcf_recvsync関数[1]、[2]

dc_mcf_reply関数[1]、[2]

dc_mcf_resend関数[1]

dc_mcf_rollback関数[1]

dc_mcf_sendrecv関数[1]、[2]

dc_mcf_sendsync関数[1]、[2]

dc_mcf_send関数[1]、[2]

dc_mcf_tactcn関数[1]

dc_mcf_tactle関数[1]

dc_mcf_tdctcn関数[1]

dc_mcf_tdctle関数[1]

dc_mcf_tdlqle関数[1]

dc_mcf_tempget関数[1]

dc_mcf_tempput関数[1]

dc_mcf_timer_cancel関数[1]

dc_mcf_timer_set関数[1]

dc_mcf_tlscn関数[1]

dc_mcf_tlscom関数[1]

dc_mcf_tlsle関数[1]

dc_mcf_tlsln関数[1]

dc_mcf_tofln関数[1]

dc_mcf_tonln関数[1]

dc_prf_get_trace_num関数[1]

dc_prf_utrace_put関数[1]

dc_rap_connect関数[1]

dc_rap_disconnect関数[1]

dc_rpc_call_to関数[1]

dc_rpc_call関数[1]

dc_rpc_cltsend関数[1]

dc_rpc_discard_further_replies関数[1]

dc_rpc_discard_specific_reply関数[1]

dc_rpc_get_callers_address関数[1]

dc_rpc_get_error_descriptor関数[1]

dc_rpc_get_service_prio関数[1]

dc_rpc_get_watch_time関数[1]

dc_rpc_mainloop関数[1]、[2]、[3]

dc_rpc_open関数[1]、[2]、[3]

dc_rpc_poll_any_replies関数[1]

dc_rpc_service_retry関数[1]

dc_rpc_set_service_prio関数[1]

dc_rpc_set_watch_time関数[1]

dc_rts_utrace_put関数[1]

dc_tam_close関数[1]

dc_tam_delete関数[1]

dc_tam_get_inf関数[1]

dc_tam_open関数[1]

dc_tam_read関数[1]

dc_tam_rewrite関数[1]

dc_tam_status関数[1]

dc_tam_write関数[1]

dc_trn_begin関数[1]、[2]

dc_trn_chained_commit関数[1]、[2]

dc_trn_chained_rollback関数[1]、[2]

dc_trn_info関数[1]

dc_trn_rm_select[1]

dc_trn_unchained_commit関数[1]、[2]

dc_trn_unchained_rollback関数[1]、[2]

dc_uto_test_status関数[1]

dc_xat_connect関数[1]

DCADM.cbl[1]

DCDAM.cbl[1]

DCDMB.cbl[1]

DCIST.cbl[1]

DCJNL.cbl[1]

DCJUP.cbl[1]

DCLCK.cbl[1]

DCLOG.cbl[1]

DCMCF.cbl[1]

DCPRF.cbl[1]

DCRAP.cbl[1]

DCRPC.cbl[1]

DCRSV.cbl[1]

dcsvstartコマンド[1]、[2]、[3]

dcsvstopコマンド[1]、[2]、[3]

DCTAM.cbl[1]

DCTRN.cbl[1]

DCUTO.cbl[1]

DCXAT.cbl[1]

delvcmdコマンド[1]、[2]

DNSのドメイン名[1]

E

ERREVT1[1]、[2]

ERREVT2[1]、[2]、[3]、[4]、[5]

ERREVT3[1]、[2]、[3]、[4]

ERREVT4[1]、[2]、[3]

ERREVTA[1]、[2]

EX[1]、[2]、[3]

I

IDLコンパイラ[1]

IDLファイル[1]

IDL-only TxRPC[1]

ISAM[1]

ISAM/B[1]

ISAMファイルサービス[1]、[2]

ISTサービス[1]、[2]、[3]

ISTテーブル[1]、[2]

ISTテーブルのオープン[1]

ISTテーブルのクローズ[1]

ISTテーブルの構造[1]

ISTテーブルの排他制御[1]

ISTテーブルへのアクセス環境[1]

ISTテーブルへのアクセス手順[1]

J

jnlrputコマンド[1]

jnlrputコマンド出力ファイル[1]

K

K&Rの形式[1]

L

lckrminfコマンド[1]

logcatコマンド[1]

M

MCF[1]

mcftendctコマンド[1]

mcfuevtコマンド[1]

MCFアプリケーション定義[1]

MCFイベント[1]、[2]

MCFイベント情報[1]

MCFイベント処理用MHP[1]、[2]

MCFイベント処理用MHPのアプリケーションの型[1]

MCFイベントの一覧[1]

MCFオンラインテスタ[1]

MCFサービス[1]

MCFサンプル[1]、[2]

MCF通信サービスに関する運用[1]

MCF通信プロセス[1]、[2]、[3]

MCF通信プロセス識別子[1]

MCFのプロセス[1]

MHP[1]、[2]、[3]

MHPの開始[1]

MHPの稼働中[1]

MHPの構成[1]

MHPの終了[1]

MHPの処理の概要[1]

MHPのトランザクション制御[1]

MHPのロールバック処理[1]

MQI[1]

N

namdomainsetupコマンド[1]

NETM[1]

NEXT検索[1]

noans型[1]

O

OpenTP1[1]

OpenTP1クライアント機能（TP1/Client）[1]

OpenTP1とUAPのネットワーク内の位置[1]

OpenTP1ノードの状態の取得[1]

OpenTP1ノードのノード識別子の取得[1]

OpenTP1の基本機能（TP1/Server Base，TP1/LiNK）[1]

OpenTP1のサンプル[1]

OSI TP[1]、[2]、[3]

OSI TPを使ったクライアント／サーバ形態の通信[1]

P

parallel_count[1]

PC[1]

PR[1]、[2]、[3]

prfトレース[1]

putenv PATH[1]

R

rapクライアント[1]

rapサーバ[1]

rapリスナー[1]

rollback_only状態[1]

RPC[1]、[2]

rpc_service_retry_count[1]

RPCインタフェース定義ファイル[1]

RPCとトランザクション属性の関係[1]

RPCとプロセスの関係[1]

RPCトレース[1]

RPCの形態[1]、[2]

S

scd_refresh_process[1]

SCMPEVT[1]、[2]

SERREVT[1]、[2]

service_priority_control[1]

SPP[1]、[2]

SPPの開始[1]

SPPの稼働中[1]

SPPの構成[1]

SPPの終了[1]

SPPの処理の概要[1]

SQL文[1]

stbmakeコマンド[1]

SUP[1]、[2]

SUPの開始[1]

SUPの稼働時[1]

SUPの終了[1]

SUPの処理の概要[1]

T

tamcreコマンド[1]

TAMサービスとDAMサービスとの互換[1]

TAMサービスの統計情報[1]

TAMサンプル[1]、[2]

TAMテーブル[1]

TAMテーブルのオープン[1]

TAMテーブルのクローズ[1]

TAMテーブルの状態を取得[1]

TAMテーブルの情報を取得[1]

TAMテーブルの排他制御[1]

TAMテーブルへアクセスするときの名称[1]

TAMテーブルへのアクセス[1]

TAMテーブルへのアクセス手順[1]

TAMテーブル名[1]

TAMのレコード追加・削除に伴う注意事項[1]

TAMファイル[1]

TAMファイルサービス[1]、[2]

TAMファイルの構成[1]

TAMファイルの作成[1]

TCP/IP[1]、[2]、[3]

TP1/Client[1]

TP1/FS/Direct Access[1]

TP1/FS/Table Access[1]

TP1/FS/Table Accessを使用した場合の出力形式[1]

TP1/LiNK[1]、[2]

TP1/Message Control[1]、[2]

TP1/Message Control/Tester[1]

TP1/Message Controlを使う場合の機能[1]

TP1/Message Queue[1]

TP1/Multiを使う場合の機能[1]

TP1/NET/Library[1]、[2]

TP1/NET/OSAS-NIF[1]

TP1/NET/OSI-TP-Extended[1]、[2]

TP1/Offline Tester[1]

TP1/Online Tester[1]

TP1/Server Base[1]、[2]

TP1/Shared Table Access[1]

tpacall()[1]

TPADVERTISE[1]

tpadvertise()[1]

tpalloc()[1]

TPCALL[1]、[2]

tpcall()[1]

TPCONNECT[1]

tpconnect()[1]

TPDISCON[1]

tpdiscon()[1]

tpfree()[1]

TPGETRPLY[1]

tpgetrply()[1]

tprealloc()[1]

TPRECV[1]

tprecv()[1]

TPRETURN[1]、[2]

tpreturn()[1]、[2]

TPSEND[1]

tpsend()[1]

tpservice()[1]

tpstbmkコマンド[1]

TPSVCSTART[1]

tptypes()[1]

TPUNADVERTISE[1]

tpunadvertise()[1]

transaction_mandatory[1]

transaction_optional[1]

trnlnkrmコマンド[1]

trnmkobjコマンド[1]

trnrmid[1]

trnstring[1]

tx_begin()[1]

tx_close()[1]

tx_commit()[1]

tx_info()[1]

tx_open()[1]

tx_rollback()[1]

tx_set_commit_return()[1]

tx_set_transaction_control()[1]

tx_set_transaction_timeout()[1]

TX_関数[1]、[2]

TX_関数の時間監視[1]

TX_関数を使用する場合の制限[1]

TXBEGIN[1]

TXCLOSE[1]

TXCOMMIT[1]

txidlコマンド[1]

TXINFORM[1]

TXOPEN[1]

TXROLLBACK[1]

TxRPCインタフェースの通信[1]

TXSETCOMMITRET[1]

TXSETTIMEOUT[1]

TXSETTRANCTL[1]

TXインタフェース[1]、[2]

U

UAP[1]

UAP異常終了通知イベント[1]

UAP異常終了通知イベント（ERREVT3）[1]

UAPからアクセスする場合の注意[1]

UAP共用ライブラリ[1]

UAP共用ライブラリの作成[1]

UAPテスタ機能[1]

UAPトレース[1]

UAPの実行形式ファイル名[1]

UAPの登録[1]

UAPの名称の関係[1]

UAPプロセス[1]

UAPを格納するディレクトリ[1]

UCMDEVT[1]

UJ[1]

UJレコード[1]

UOC[1]

V

VCLSEVT[1]、[2]

VERREVT[1]、[2]

VOPNEVT[1]、[2]

W

WAN[1]

WS[1]

X

X_C_TYPE[1]

X_COMMON[1]

X_OCTET[1]

XATMIインタフェース[1]、[2]、[3]

XATMIインタフェース定義[1]

XATMIインタフェース定義ファイル[1]

XATMIインタフェースのライブラリ関数[1]

XATMI通信サービス[1]

XAインタフェース[1]、[2]

あ

アクセスするときの条件[1]

アクセスの概要[1]

アプリケーション起動プロセス[1]、[2]、[3]

アプリケーションに関するタイマ起動要求の削除[1]

アプリケーションの型[1]、[2]

アプリケーションプログラミングインタフェースの機能[1]

アプリケーションプログラム[1]

アプリケーションプログラムの環境設定[1]

アプリケーションプログラムの起動[1]

アプリケーションプログラムの作成[1]

アプリケーションプログラムの種類[1]

アプリケーションプログラムを起動する方法[1]

アプリケーション名[1]、[2]、[3]

アプリケーション名決定UOC[1]

い

一時記憶データ[1]

一時記憶データの受け取り[1]

一時記憶データの更新[1]

一方受信形態[1]

イベントの受信[1]

入り口点[1]、[2]

インタフェース定義言語ファイル[1]

インデクス部[1]、[2]

う

運用コマンドの実行[1]

運用操作で使える関数[1]

え

エラーイベント[1]

エントリポイント[1]、[2]

お

応答型（ans型）[1]

応答型RPC[1]

応答の長さ[1]

応答待ち時間の設定を参照する[1]

応答を受け取る領域の長さ[1]

応答を格納する領域[1]

オートコネクトモード[1]

オフライン中のDAMファイルのアクセス[1]

オフラインテスタ[1]

オフラインの業務をするUAP[1]、[2]

オリジネータ[1]

オンライン時とオフライン時の排他[1]

オンライン中のDAMファイルのアクセス[1]

オンラインテスタ[1]、[2]

オンラインテスタの管理[1]

オンライントランザクション処理[1]

か

回復対象外のDAMファイル[1]

回復対象外のDAMファイルの排他制御[1]

回復対象外のDAMファイルの排他範囲[1]

回復対象外のDAMファイルへのアクセス[1]

会話型サービスの通信[1]、[2]

拡張RM登録定義[1]

型付きバッファ[1]、[2]

型付きレコード[1]、[2]

環境設定[1]

監査ログの出力[1]

関数の一覧[1]

き

記述子[1]

キュー受信型サーバ[1]、[2]

共用モード[1]、[2]、[3]

く

クライアント／サーバ形態のUAP[1]

クライアント／サーバ形態のUAPでのトランザクション処理[1]

クライアント／サーバ形態のUAPの概要[1]

クライアント／サーバ形態の通信で使うUAP[1]

クライアント／サーバ形態の通信のトランザクション[1]

クライアント／サーバ形態の通信プロトコル[1]

クライアントUAP[1]

クライアントUAPのノードアドレスの取得[1]

クライアントユーザプログラム[1]

クラスタ／並列システム[1]

グローバルトランザクション[1]

け

経過時間指定のタイマ起動[1]

継続問い合わせ応答型（cont型）[1]、[2]

継続問い合わせ応答形態[1]

継続問い合わせ応答の終了[1]

継続問い合わせ応答の処理[1]

結合[1]、[2]

現在のトランザクションに関する情報を報告[1]

こ

更新目的の排他[1]、[2]、[3]

構造体[1]

コーディング[1]

コネクション解放通知イベント（CCLSEVT，VCLSEVT）[1]

コネクション確立通知イベント（COPNEVT，VOPNEVT）[1]

コネクションの解放[1]

コネクションの確立[1]

コネクションの確立と解放[1]

コネクションを再確立・強制解放する場合のコーディング例[1]

コネクトモード[1]

コマンド[1]

コマンドを使ったMHPの起動[1]

コミット[1]、[2]、[3]

コミット最適化[1]

コミット処理[1]

コンパイル[1]、[2]

さ

サーバ[1]

サーバUAP[1]

サーバUAPの作成方法[1]

サービス[1]

サービス関数[1]、[2]

サービス関数実行時間の監視[1]

サービス関数とスタブの関係[1]

サービス関数のリトライ[1]

サービスグループ名[1]、[2]

サービス提供プログラム[1]、[2]

サービスのネスト[1]

サービスの要求方法[1]

サービスプログラム[1]

サービス名[1]、[2]、[3]

サービス要求の応答待ち時間の参照と更新[1]

サービス利用プログラム[1]、[2]

再帰呼び出し[1]

最終セグメント[1]

再送対象メッセージの指定内容[1]

再送できるメッセージの条件[1]

サブオーディネータ[1]

サブタイプ[1]

参照目的の排他[1]、[2]、[3]

サンプル[1]

サンプルシナリオテンプレート[1]

サンプルプログラムの仕様[1]

し

シーケンシャルアクセス[1]

時間監視[1]、[2]、[3]

資源の排他制御[1]、[2]

時刻指定のタイマ起動[1]

システム運用の管理[1]、[2]

システムジャーナルファイル[1]

自動起動[1]

ジャーナルデータの編集[1]、[2]

出力メッセージの編集UOC[1]

手動起動[1]

順処理[1]

障害通知イベント[1]

障害通知イベント（CERREVT，VERREVT）[1]

常設コネクション[1]

常設コネクションでの連鎖RPC[1]

状態通知イベント[1]

常駐プロセス[1]、[2]、[3]

処理結果の受信を拒否[1]

処理できなかったメッセージ[1]

す

スケジュールの優先度（スケジュールプライオリティ）[1]

スケジュールプライオリティの設定[1]

スタブ[1]、[2]、[3]

スタブが必要なUAP[1]

スタブの作成[1]

スタブの作成手順[1]

スタブの種類[1]

スタブを使用する場合（SPP）[1]

ステータスコード[1]

せ

性能検証用トレースの取得[1]

セクタ長[1]

セグメント[1]

セグメントの構造[1]

先頭検索[1]

先頭セグメント[1]

全レコード検索[1]

そ

送信完了通知イベント[1]

送信完了通知イベント（SCMPEVT）[1]

送信障害通知イベント[1]

送信障害通知イベント（SERREVT）[1]

送信メッセージの通番編集UOC[1]

相対ブロック番号[1]

ソースファイル[1]、[2]、[3]

即時起動[1]

ソケット受信型サーバ[1]、[2]

ソケット受信型サーバへの連鎖RPC[1]

た

タイプ[1]

タイプトバッファ[1]、[2]

タイプトレコード[1]、[2]

タイマ起動[1]

タイマ起動の引き継ぎの定義[1]

タイマ起動引き継ぎ決定UOC[1]、[2]

タイマ起動メッセージ廃棄通知イベント[1]

タイマ起動メッセージ廃棄通知イベント（ERREVT4）[1]

タイムアウト情報[1]、[2]

タイムアウト情報の出力形式[1]

ち

中間以降のセグメント[1]

つ

通常のトランザクション処理（2相コミット）の概要[1]

通信イベント[1]

通信イベント障害時にエラーイベント通知する[1]、[2]

通信イベント処理用SPP[1]

通信形態で使える関数[1]

通信先を指定したRPC[1]

通信データの型[1]

通信の形態[1]

ツリー形式[1]

て

データ圧縮機能[1]

データの受け渡し[1]

データ部[1]

データファイル部[1]

データベース言語[1]

データベースにアクセスする場合[1]

テーブル記述子[1]、[2]

テーブル排他[1]

テーブル排他なしTAMテーブルアクセス機能[1]

テーブルプール不足のとき[1]

テスタ[1]

テストできるアプリケーションプログラム[1]

デッドロックが起こったときの処置[1]

デッドロック時のOpenTP1の処置[1]

デッドロック時のUAPの処置[1]

デッドロック情報[1]、[2]、[3]

デッドロック情報の出力形式[1]、[2]

デッドロックを避けるための注意[1]

デバッガ[1]

テンプレート[1]、[2]

と

問い合わせ応答形態[1]

同期応答型RPC[1]

同期応答型RPCと同期点の関係[1]、[2]

同期応答型RPCの時間監視[1]

同期型のメッセージ受信[1]

同期型のメッセージ処理[1]

同期型のメッセージ処理とロールバック[1]

同期型のメッセージ処理の時間監視[1]

同期型のメッセージ送受信[1]

同期型のメッセージ送信[1]

同期受信[1]

同期送受信[1]

同期送信[1]

同期点[1]、[2]

同期点の取得[1]

統計情報[1]、[2]

ドメイン修飾をしたサービス要求[1]

ドメイン名[1]

トランザクション[1]

トランザクション処理[1]

トランザクション処理からのDAMファイルブロックへのアクセス[1]

トランザクション処理での注意事項[1]

トランザクション処理の時間監視[1]

トランザクション制御[1]、[2]、[3]、[4]、[5]、[6]

トランザクション属性[1]、[2]、[3]

トランザクション属性なし[1]

トランザクション属性のUAP[1]

トランザクション属性の指定[1]

トランザクションタイムアウト[1]、[2]

トランザクションとTAMアクセスの関係[1]

トランザクションの開始と同期点の取得[1]

トランザクションの最適化[1]、[2]

トランザクションの処理から非トランザクショナルRPCの発行[1]、[2]

トランザクションを制御する関数を使えるUAP[1]

に

入力パラメタ[1]

入力パラメタ長[1]

入力メッセージの編集UOC[1]

入力元論理端末名称[1]

任意のブロックを入出力する場合[1]

ね

ネットワーク内の位置[1]

の

ノーアクセス最適化[1]

ノード[1]

ノード間負荷バランス拡張機能[1]

ノード間負荷バランス機能[1]、[2]

ノード識別子[1]

ノードについて[1]

は

パーソナルコンピュータ[1]

排他解除待ちの設定[1]、[2]

排他解除待ちの設定（回復対象のDAMファイルの場合）[1]

排他制御[1]、[2]、[3]、[4]

排他制御モード[1]、[2]、[3]

排他なし参照使用時の注意事項[1]

排他の解除方法[1]

排他の指定単位[1]

排他の指定単位（回復対象のDAMファイルの場合）[1]

排他の対象となる資源[1]

排他のテスト[1]

排他待ち限界経過時間の指定[1]

排他モード[1]、[2]、[3]

バインドモード[1]、[2]

ハッシュ形式[1]

バッファ形式1[1]

バッファ形式2[1]

ひ

非応答型（noans型）[1]

非応答型RPC[1]、[2]

非応答型RPCと同期点の関係[1]、[2]

非オートコネクトモード[1]

非常駐UAPプロセスのリフレッシュ機能[1]

非常駐プロセス[1]、[2]、[3]

非問い合わせ応答形態[1]

非同期応答型RPC[1]

非同期応答型RPC（処理結果の受信を拒否）[1]

非同期応答型RPCと同期点の関係[1]

非同期応答型RPCの応答の受信[1]

非同期応答型RPCの時間監視[1]

非同期型のメッセージ受信[1]

非同期型のメッセージ送信[1]

非同期プリペア最適化[1]

非トランザクショナルRPC[1]

非トランザクション属性のMHP[1]

非トランザクション属性のMHPの時間監視[1]

ヒューリスティック決定[1]

ヒューリスティック発生時の処置[1]

非連鎖モードのコミット[1]

非連鎖モードのロールバック[1]

ふ

ファイル記述子[1]、[2]、[3]

ファイル排他[1]

負荷分散[1]

負荷分散とスケジュール[1]

複数ブロックの一括入出力[1]、[2]

複数レコードの一括入出力[1]

不正アプリケーション名検出通知イベント[1]

不正アプリケーション名検出通知イベント（ERREVT1）[1]

物理ファイル[1]

物理ファイルの作成[1]

物理ファイル名[1]

プリペア最適化[1]

プリペア処理[1]

プロセス[1]、[2]

プロセスタイプ[1]

プロセスの設定方法[1]

プロセスの負荷分散[1]

ブロッキングタイムアウト[1]、[2]

ブロック[1]

ブロックの参照／更新手順[1]

ブロックの初期作成と再作成[1]

ブロック排他[1]

分岐送信[1]

へ

並行処理[1]

ヘッダ領域[1]

ほ

翻訳[1]、[2]

ま

マスタスケジューラデーモン[1]

マネジャ[1]

マルチサーバ[1]、[2]、[3]

マルチサーバ負荷バランス[1]

マルチスケジューラ機能[1]

マルチスケジューラ機能の検討が必要なシステム構成例[1]

マルチスケジューラ機能を使用したRPC[1]

マルチスケジューラデーモン[1]

マルチノードエリア[1]

マルチノード機能[1]、[2]

マルチノード機能の関数を使える条件[1]

マルチノードサブエリア[1]

み

未決着トランザクション情報[1]

未決着トランザクション情報の出力形式[1]

未処理送信メッセージ廃棄通知イベント[1]

未処理送信メッセージ廃棄通知イベント（ERREVTA）[1]

め

メイン関数[1]、[2]

メインフレーム[1]

メインプログラム[1]

メッセージキュー[1]

メッセージキューイング機能[1]

メッセージキューインタフェース[1]

メッセージ形式[1]

メッセージ構造[1]

メッセージ処理プログラム[1]、[2]

メッセージ送受信[1]、[2]

メッセージ送受信形態のUAP[1]

メッセージ送受信形態の通信で使うUAP[1]

メッセージ送受信形態のトランザクション処理[1]

メッセージの構造[1]

メッセージの再送[1]

メッセージの受信[1]

メッセージの送信[1]

メッセージの通信形態[1]

メッセージ廃棄通知イベント[1]

メッセージ廃棄通知イベント（ERREVT2）[1]

メッセージログ通知の受信[1]

メッセージログの出力[1]、[2]

メッセージログファイル[1]

メッセージログをアプリケーションプログラムから出力[1]

ゆ

ユーザアプリケーションプログラムと業務形態の関係[1]

ユーザオウンコーディング（UOC）[1]

ユーザサーバ[1]、[2]

ユーザサーバの状態遷移（SPP，MHP）[1]

ユーザサーバの状態遷移（SUP）[1]

ユーザサーバの状態遷移（ソケット受信型サーバ　SPP）[1]

ユーザサーバの状態の検知[1]

ユーザサーバの状態の取得[1]

ユーザサーバのテスト状態[1]

ユーザサーバプロセス[1]

ユーザサーバ名[1]、[2]

ユーザジャーナルの取得[1]、[2]

ユーザタイマ監視機能[1]

ユーザデータを使う場合の機能[1]

ユーザファイルの初期化をするUAP[1]

ら

ライブラリ関数[1]、[2]

ライブラリ関数の一覧[1]

乱処理[1]

ランダムアクセス[1]

り

リアルタイム取得項目定義テンプレート[1]

リアルタイム統計情報の取得[1]、[2]

リードオンリー最適化[1]、[2]、[3]

リードオンリー最適化の概要[1]

リカーシブコール[1]

リクエスト／レスポンス型サービスの通信[1]、[2]

リソースマネジャ[1]

リソースマネジャ接続先選択機能[1]

リターン値[1]

リトライ[1]

リモートAPI機能[1]

リモートプロシジャコール[1]、[2]、[3]、[4]

リモートプロシジャコールでのデータの受け渡し[1]

リモートプロシジャコールとサービスを実行するプロセスの関連[1]

リモートプロシジャコールの形態[1]

リモートプロシジャコールの形態と同期点の関係[1]

リモートプロシジャコールの実現方法[1]

リモートプロシジャコールのデータの受け渡し[1]

リンケージ[1]、[2]

リンケージ時のバインドモード[1]、[2]

れ

レコード[1]、[2]

レコードの入力／更新／追加／削除手順[1]

レコード排他[1]

連鎖RPC[1]、[2]

連鎖RPCと同期点の関係[1]

連鎖RPCの開始[1]

連鎖RPCの時間監視[1]

連鎖RPCの終了[1]

連鎖RPCを使った最適化[1]

連鎖モードのコミット[1]

連鎖モードのロールバック[1]

ろ

ロールバック[1]、[2]、[3]、[4]、[5]

ロールバック最適化[1]

ログサービス定義[1]

ロックマイグレーション[1]

論理端末の出力キュー削除[1]

論理端末の状態表示[1]

論理端末の閉塞と閉塞解除[1]

論理ファイル[1]

論理ファイル名[1]

論理閉塞と解除[1]

論理メッセージ[1]

論理メッセージとセグメント[1]

わ

ワークステーション[1]