![]() |
![]() |
|
|
bankapp サーバと bankapp サービスの検証
ここでは、次の内容について説明します。
サーバとは、1 つ以上のサービスを提供する実行可能プロセスです。BEA Tuxedo システムでは、サーバはクライアントとして動作するプロセスから継続的に要求を受け取り、それを適切なサービスに転送します。サービスとは、アプリケーションの処理を行うために記述された C 言語のサブルーチンです。BEA Tuxedo アプリケーションは、サービスを提供し、リソース・マネージャにアクセスできるように作成されています。サービス・ルーチンは、BEA Tuxedo アプリケーション・プログラマが作成します。
データベースと直接やり取りは行わない TRANSFER サービスを除くすべての bankapp サービスのコードは、C 言語に埋め込み型 SQL 文が使用されています。TRANSFER サービスは、XFER サーバによって実行される C 言語プログラムです。つまり、ソース・ファイルは .ec ファイルではなく .c ファイルです。
bankapp のすべての bankapp サービスでは、ATMI で提供される関数を使用して、次の処理が行われます。
bankapp の要求/応答型サーバ
bankapp の 5 つのサーバは、応答/要求モードで動作します。このうちの 4 つは、埋め込み型 SQL 文を使用して、リソース・マネージャにアクセスします。これらのサーバのソース・ファイル (bankapp サンプル・アプリケーションのサブディレクトリにあります) には、ファイル名に拡張子として .ec が付いています。
5 番目のサーバ XFER は振り替えに使用されるサーバで、リソース・マネージャ自体への呼び出しは行いません。このサーバは、TLR サーバによって提供される WITHDRAWAL サービスおよび DEPOSIT サービスを呼び出し、口座間の振り替えを行います。XFER では、リソース・ネージャへの呼び出しは行われず、埋め込み型 SQL 文が使用されていないので、XFER のソース・ファイルは .c ファイルです。
bankapp 会話型サーバ AUDITC は、会話型サーバの一例です。このサーバでは、AUDITC と呼ばれるサービスが提供されます。会話型クライアント auditcon は、AUDITC への接続を確立し、そこに監査情報を要求します。 AUDITC は要求を評価し、必要な情報を得るために適切なサービス (ABAL、TBAL、ABAL_BID、またはTBAL_BID) を呼び出します。呼び出されたサービスから応答を受信すると、AUDITC はその応答を auditcon に返します。会話型サーバのサービスは、要求/応答サービスを呼び出すことができます。別の会話型サーバとの接続を確立することもできますが、この機能は AUDITC では提供されていません。 bankapp サービス bankapp では、12 種類の要求/応答サービスが提供されます。bankapp の各サービス名は、サーバのソース・コード内にある C 言語の関数名と一致します。
bankapp サービスのアルゴリズム 次の疑似コードは、bankapp の各サービスで使用されるアルゴリズムを示しています。サービスには BR_ADD、TLR_ADD、OPEN_ACCT、CLOSE_ACCT、WITHDRAWAL、DEPOSIT、INQUIRY、 TRANSFER、ABAL、TBAL、ABAL_BID、および TBAL_BID があります。このコード例を参考にすると、bankapp サーバのソース・コードを理解しやすくなります。 BR_ADD の疑似コード TLR_ADD の疑似コード OPEN_ACCT の疑似コード CLOSE_ACCT の疑似コード WITHDRAWAL の疑似コード DEPOSIT の疑似コード INQUIRY の疑似コード TRANSFER の疑似コード ABAL の疑似コード TBAL の疑似コード ABAL_BID の疑似コード TBAL_BID の疑似コード サーバに組み込みのユーティリティ bankapp のソース・ファイルには、appinit.c と util.c という 2 つの C 言語サブルーチン・ファイルがあります。void BR_ADD (TPSVCINFO *transb)
{
TPSVCINFO データ・バッファへのポインタを設定;
フィールド化バッファからサービス要求に関連するすべての値を取得;
BRANCH にレコードを挿入;
tpreturn() で成功を示す値を返す;
}void TLR_ADD (TPSVCINFO *transb)
{
TPSVCINFO データ・バッファへのポインタを設定;
フィールド化バッファからサービス要求に関連するすべての値を取得;
支店の LAST_ACCT を読み取り TELLER_ID を取得;
窓口レコードの挿入;
LAST_TELLER で BRANCH を更新;
tpreturn() で成功を示す値を返す;
}void OPEN_ACCT(TPSVCINFO *transb)
{
Fget() および Fvall() で、フィールド化バッファからサービス要求に関連するすべての値を取得;
預け入れ金額が正の値であるか確認し、正でない場合は tpreturn() でエラーを示す値を返す;
口座番号が妥当であるか確認し、妥当でなければ tpreturn() でエラーを示す値を返す;
トランザクション整合性レベルを、読み取り/書き込みに設定;
支店の LAST_ACCT フィールドに基づき、BRANCH レコードを検索し、新たな口座番号を選択;
ACCOUNT ファイルに新たな口座レコードを挿入;
LAST_ACCT で BRANCH レコードを更新;
tpalloc() で預け入れ要求バッファを割り当て、Finit() で初期化し FML タイプとして使用;
DEPOSIT サービス要求への値を預け入れバッファに格納;
サービスからの呼び出しにより DEPOSIT 要求の優先順位を上げる;
tpcall() で DEPOSIT サービスを呼び出し、初期残高を加算;
必要な情報を含む応答バッファを用意;
tpfree()で預け入れ要求バッファを解放;
tpreturn() で成功を示す値を返す;
}void CLOSE_ACCT(TPSVCINFO *transb)
{
Fvall() でフィールド化バッファから口座番号を取得;
口座番号が妥当であるか確認し、妥当でなければ tpreturn() でエラーを示す値を返す;
トランザクション整合性レベルを、読み取り/書き込みに設定;
最終的な引き出し金額の確認のため、ACCOUNT レコードを検索;
tpalloc() を使用して引き出し要求バッファを割り当て、Finit() で初期化し FML タイプとして使用;
WITHDRAWAL サービス要求への値を引き出しバッファに格納;
サービスからの呼び出しにより DEPOSIT 要求の優先順位を上げる;
tpcall() で WITHDRAWAL サービスを呼び出し、口座残高を引き出す;
ACCOUNT レコードを削除;
必要な情報を含む応答バッファを用意;
tpfree() で引き出し要求バッファを解放;
tpreturn() で、成功を示す値を返す;
}void WITHDRAWAL(TPSVCINFO *transb)
{
Fvall() および Fget() で、フィールド化バッファから口座番号と金額を取得;
口座番号が妥当であるか確認し、妥当でなければ tpreturn() でエラーを示す値を返す;
引き出し金額が正の値であるか確認し、正でなければ tpreturn() でエラーを示す値を返す;
トランザクション整合性レベルを、読み取り/書き込みに設定;
口座残高を取得するため、 ACCOUNT レコードを検索;
引き出し金額が ACCOUNT で示される残高を超えないか確認;
窓口残高と支店番号を取得するため、TELLER レコードを検索;
引き出し金額が TELLER の残高を超えないか確認;
支店残高を取得するため、BRANCH レコードを検索;
引き出し金額が BRANCH の残高を超えないか確認;
引き出し金額を差し引き、新たな口座残高を決定;
新たな口座残高で ACCOUNT レコードを更新;
引き出し金額を差し引き、新たな窓口残高を決定;
新たな窓口残高で TELLER レコードを更新;
引き出し金額を差し引き、新たな支店残高を決定;
支店残高で BRANCH レコードを更新;
トランザクション情報と共に、新たな HISTORY レコードを挿入;
必要な情報を含む応答バッファを用意;
tpreturn() で、成功を示す値を返す;
}void DEPOSIT(TPSVCINFO *transb)
{
Fvall() および Fget() で、フィールド化バッファから口座番号と金額を取得;
口座番号が妥当であるか確認し、妥当でなければ tpreturn() でエラーを示す値を返す;
預け入れ金額が正の値であるか確認し、正でなければ tpreturn() でエラーを示す値を返す;
トランザクション整合性レベルを、読み取り/書き込みに設定;
口座残高を取得するため、 ACCOUNT レコードを検索;
窓口残高と支店番号を取得するため、TELLER レコードを検索;
支店残高を取得するため、BRANCH レコードを検索;
預け入れ金額を加算し、新たな口座残高を決定;
新たな口座残高で ACCOUNT レコードを更新;
預け入れ金額を加算し、新たな窓口残高を決定;
新たな窓口残高で TELLER レコードを更新;
預け入れ金額を加算し、新たな支店残高を決定;
支店残高で BRANCH レコードを更新;
トランザクション情報と共に、新たな HISTORY レコードを挿入;
必要な情報を含む応答バッファを用意;
tpreturn() で成功を示す値を返す;
}void INQUIRY(TPSVCINFO *transb)
{
Fvall() でフィールド化バッファから口座番号を取得;
口座番号が妥当であるか確認し、妥当でなければ tpreturn() でエラーを示す値を返す;
トランザクション整合性レベルを、読み取りのみに設定;
口座残高を取得するため、 ACCOUNT レコードを検索;
必要な情報を含む応答バッファを用意;
tpreturn() で成功を示す値を返す;
}void TRANSFER(TPSVCINFO *transb)
{
Fvall() および Fget() で、フィールド化バッファから、口座番号と金額を取得;
口座番号が両方とも妥当であるか確認し、妥当でない場合は、tpreturn() でエラーを示す値を返す;
振り替え金額が正の値であるか確認し、正でない場合は tpreturn() でエラーを示す値を返す;
tpalloc() を使用して引き出し要求バッファを割り当て、 Finit() で初期化し FML タイプとして使用;
WITHDRAWAL サービス要求への値を引き出し要求バッファに格納;
サービスからの呼び出しにより DEPOSIT 要求の優先順位を上げる;
tpcall() で WITHDRAWAL サービスを呼び出す;
応答要求バッファから情報を取得;
預け入れ要求バッファとして使用するため、引き出し要求バッファを Finit() により再度初期化;
DEPOSIT サービス要求への値を預け入れ要求のバッファに格納;
DEPOSIT 要求の優先順位を上げる;
tpcall() で DEPOSIT サービスを呼び出す;
必要な情報を含む応答バッファを用意;
tpfree() で引き出し/預け入れ要求バッファの解放;
tpreturn() で成功を示す値を返す;
}void ABAL(TPSVCINFO *transb)
{
トランザクション整合性レベルを、読み取りのみに設定;
ABAL サーバ・グループのデータベースで、 ACCOUNT ファイルのすべての BALANCE 値の合計を検索
(単一の ESQL 文で十分);
合計を応答バッファ・データ構造体へ格納;
tpreturn() で成功を示す値を返す;
}void TBAL(TPSVCINFO *transb)
{
トランザクション整合性レベルを、読み取りのみに設定;
TBAL サーバ・グループのデータベースで、 TELLER ファイルのすべての BALANCE 値の合計を検索
(単一の ESQL 文で十分);
合計を応答バッファ・データ構造体へ格納;
tpreturn() で成功を示す値を返す;
}void ABAL_BID(TPSVCINFO *transb)
{
トランザクション整合性レベルを、読み取りのみに設定;
transb バッファに基づき、branch_id を設定;
BRANCH_ID = branch_id に該当するレコードの中で、 ACCOUNT ファイルのすべての BALANCE 値
の合計を検索 (単一の ESQL 文で十分);
合計を応答バッファ・データ構造体へ格納;
tpreturn() で成功を示す値を返す;
}void TBAL_BID(TPSVCINFO *transb)
{
トランザクション整合性レベルを、読み取りのみに設定;
transb バッファに基づき、branch_id を設定;
BRANCH_ID = branch_ID に該当するレコードの中で、 TELLER ファイルのすべての BALANCE 値
の合計を検索 (単一の ESQL 文で十分);
合計を応答バッファ・データ構造体へ格納;
tpreturn() で成功を示す値を返す;
}
サービスをコーディングする別の方法
bankapp のソース・ファイルでは、すべてのサービスがサーバのソース・コードとして参照されるファイルに組み込まれています。これらのファイルは bankapp サーバと名前が同じですが、main() 関数が含まれていないので実際にはサーバではありません。標準 main() は、buildserver コマンドの実行時に BEA Tuxedo ATMI によって提供されます。
BEA Tuxedo システム・アプリケーションを作成する別の方法として、各サービス・サブルーチンを別のファイルに記述する方法があります。この方法を使用して、TLR サーバを作成するとします。 TLR.ec ファイルには 3 つのサービスが定義されています。次の手順に従って、これらのサービスを INQUIRY.ec、WITHDRAW.ec、および DEPOSIT.ec の 3 つの .ec ファイルに分けます。
buildserver -r TUXEDO/SQL \
-s DEPOSIT -s WITHDRAWAL -s INQUIRY \
-o TLR \
-f DEPOSIT.o -f WITHDRAW.o -f INQUIRY.o \
-f util.o -f -lm
注記 上記のコマンド行のバックスラッシュは、改行を明示的に示すために表記されているだけです。コマンドとオプションは 1 行に入力できます。
この例に示したように、すべてのサービス関数を 1 つのソース・ファイルに記述する必要はありません。つまり、サーバはソース・プログラム・ファイルとして存在する必要はありません。サーバは、各種のソース・ファイルを使用して、buildserver コマンド行に指定されたファイルに基づいて 1 つの実行可能サーバとしてビルドできます。この方法により、サーバを柔軟にビルドできるようになります。
関連項目
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|