グローバルトランザクション運用を行うためには、CORBAのクライアントアプリケーションの処理に加えて、CosTransactions.Current.commitメソッドなどのCurrentインタフェースを呼び出して、データベース連携サービスにトランザクション処理を依頼します。
これらの処理を考慮したクライアントアプリケーションの構成について以下に示します。
■初期化処理部
クライアントアプリケーションをCORBAサービスに登録、およびトランザクションサービスの初期化を行います。
■アプリケーション固有部
アプリケーション固有の処理部です。トランザクションの開始から終了までの流れを記述します。
■トランザクション用ライブラリ
データベース連携サービスが提供するクライアントアプリケーション用ライブラリです。
クライアントアプリケーションの基本形を以下に示します。
try{ /* 初期化処理 */ : orb = org.omg.CORBA.ORB.init(args, null); : /* ネーミングサービスのオブジェクトリファレンスの獲得 */ : org.omg.CORBA.Object _tmpObj2 = Orb.resolve_initial_references("NameService"); Cos = org.omg.NamingContextExtHelper.narrow(_tmpObj2); … (1) : /* トランザクション依頼処理 */ org.omg.CORBA.Object _tmpObj1 = Orb.resolve_initial_references("TransactionCurrent"); Current = org.omg.CosTransactions.CurrentHelper.narrow(_tmpObj1); … (2) : /* サーバアプリケーションのオブジェクトリファレンス獲得 */ String NCid = new String("bankA::accountA"); String NCkind = new String(""); try { NameComponent nc = new NameComponent( NCid, NCkind ); NameComponent NCo[] = { nc }; Obj = Cos.resolve( NCo ); target = accountAHelper.narrow( Obj ); } Current.begin(); … (3) : obj->ope1(para); … (4) Current.commit(rhuristic); … (5) } catch( org.omg.CORBA.SystemException e) { Current.rollback(); … (6) } catch( java.lang.Exception e) { Current.rollback(); … (6) }
ネーミングサービスからサーバアプリケーションのオブジェクトリファレンスを獲得します。
Currentインタフェースのオブジェクトリファレンスを獲得します。
CosTransactions.Current.beginメソッドでトランザクションの開始を宣言します。
サーバアプリケーションを呼び出します。
サーバアプリケーションの復帰状態を確認して、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions.Current.commitメソッドでトランザクションをコミットします。
異常終了する場合は、CosTransactions.Current.rollbackメソッドでトランザクションをロールバックします。
クライアントアプリケーションからサーバアプリケーションを呼び出す形態を以下に示します。
サーバアプリケーションを呼び出し、サーバアプリケーションのメソッドが終了した時点でクライアントアプリケーションに制御が戻ります。
サーバアプリケーションを呼び出し、サーバアプリケーションのメソッドの終了を待たずにクライアントアプリケーションに制御が戻ります。クライアントアプリケーションは任意のタイミングでサーバアプリケーションのメソッドの終了を問い合わせます。
■同期型
同期型呼出しは、クライアントアプリケーションからサーバアプリケーションを呼び出し、そのサーバアプリケーションの処理終了を待ち合わせる呼出し形態です。同期型の呼出し形態について、以下に示します。
同期型には、以下の2つのインタフェースがあります。詳細については、“リファレンスマニュアル(API編)”を参照してください。
静的起動インタフェース
サーバアプリケーションのメソッド名を指定して呼び出します。
動的起動インタフェース
Requestインタフェースのinvokeメソッドでサーバアプリケーションを呼び出します。
動的起動インタフェースにおいて、遅延同期送信を行う場合の注意事項を以下に示します。
遅延同期送信の呼出し元は、その呼出しの復帰が完了するまでデータベースの操作を禁止します。
遅延同期送信の呼出し先は、データベースを使用する場合には、複数の呼出しが同じデータベースにアクセスできません。
遅延同期送信で呼び出されたアプリケーションから、同時に同一のデータベースを操作することはできません。
遅延同期送信で呼び出されたアプリケーションから、異なるデータベースを操作することができます。
同期型を使用する場合のクライアントアプリケーションの処理論理を以下に示します。
サーバアプリケーションAのメソッド1を呼び出します。クライアントアプリケーションは、サーバアプリケーションAのメソッドが終了するまで待ち合わせます。
クライアントアプリケーションは、サーバアプリケーションAのメソッド1の処理が終了した時点で制御が戻ります。
サーバアプリケーションBのメソッド2を呼び出します。クライアントアプリケーションは、サーバアプリケーションBのメソッドが終了するまで待ち合わせます。
クライアントアプリケーションは、サーバアプリケーションBのメソッド2の処理が終了した時点で制御が戻ります。
■非同期型
非同期型呼出しは、クライアントアプリケーションからサーバアプリケーションを呼び出し、サーバアプリケーションのメソッドの終了を待たずにクライアントアプリケーションに制御が戻ります。クライアントアプリケーションは任意のタイミングでサーバアプリケーションのメソッドの終了結果を問い合わせる呼出し形態です。
非同期型の呼出し形態を以下に示します。
Requestインタフェースを使用します。詳細については、“リファレンスマニュアル(API編)”を参照してください。
非同期型を使用する場合のクライアントアプリケーションの処理論理を以下に示します。
サーバアプリケーションAのメソッド1を非同期型で呼び出します。
サーバアプリケーションBのメソッド2を非同期型で呼び出します。
メソッド1の処理終了を問い合わせます。
メソッド2の処理終了を問い合わせます。
静的起動インタフェースでサーバアプリケーションを呼び出す場合の、クライアントアプリケーションの記述例について説明します。
■初期化
初期化処理として、ORBのオブジェクトリファレンスを取得します。オブジェクトリファレンスを取得するには、初期化メソッドを呼び出します。
記述例を以下に示します。
public class Sample { // クラスの宣言 public static void main( String args[] ) { org.omg.CORBA.ORB Orb; // ORBオブジェクト try { // ORBの生成と初期化 Orb = org.omg.CORBA.ORB.init( args, null ); ... } catch( java.lang.Exception e ) { ... // 例外処理 } } }
public class Sample extends java.applet.Applet { // appletクラスの宣言 public void init() { ... // 画面表示処理 } public void start() { org.omg.CORBA.ORB Orb; // ORB用オブジェクト try { // ORBの生成と初期化 Orb = org.omg.CORBA.ORB.init( this, null ); ... } catch( java.lang.Exception e ) { ... // 例外処理 } }
■ネーミングサービスのオブジェクトリファレンスの獲得
実行するオブジェクトをネーミングサービスから検索するために、ネーミングサービスのオブジェクトリファレンスを取得します。ネーミングサービスのオブジェクトリファレンスには、CORBAインタフェースのオブジェクトリファレンスの取り出しメソッドを使用します。
処理の記述例を以下に示します。
// NamingService用オブジェクトリファレンス org.omg.CosNaming.NamingContextExt Cos; // ネーミングサービスのオブジェクトリファレンスの取得 try { org.omg.CORBA.Object _tmpObj = Orb.resolve_initial_references( "NameService" ); Cos = org.omg.CosNaming.NamingContextExtHelper.narrow( _tmpObj ); ... } catch( java.lang.Exception e ) { ... // 例外処理 }
■サーバアプリケーションのオブジェクトリファレンスの獲得
ネーミングサービスのメソッドCosNaming.NamingContext.resolve()により、これから実行したいサーバアプリケーションのオブジェクトリファレンスを取り出します。検索したいオブジェクト名を当メソッドのパラメタとして指定します。
処理の記述例を以下に示します。
// ネーミングサービスのresolveメソッドを発行して // サーバアプリケーションのオブジェクトリファレンスの獲得 String NCid = new String( "ODdemo::calculator" ); // オブジェクト名 String NCkind = new String( "" ); // オブジェクトタイプ try { org.omg.CosNaming.NameComponent nc = new NameComponent( NCid, NCkind ); org.omg.CosNaming.NameComponent NCo[] = { nc }; // NamingServiceのresolveメソッド発行 org.omg.CORBA.Object Obj = Cos.resolve( NCo ); ... } catch( java.lang.Exception e ) { ... // 例外処理 }
トランザクションを開始するために、Currentインタフェースのオブジェクトリファレンスを取得し、CosTransactions.Current.beginメソッドを呼び出します。
処理の記述例を以下に示します。
static org.omg.CosTransactions.Current current; // トランザクション開始オブジェクトリファレンス // トランザクション開始インタフェースのオブジェクトリファレンスを獲得 org.omg.CORBA.Object _tmpObj1 = Orb.resolve_initial_references("TransactionCurrent"); current = org.omg.CosTransactions.CurrentHelper.narrow(_tmpObj1); // トランザクション開始メソッドの呼出し current.begin();
サーバプログラムのメソッドを呼び出します。メソッド名はIDLで指定したモジュール名、インタフェース名およびオペレーション名をドット(.)でつなげた形式で指定します。この例では、ODdemo、calculator、calculateがそれにあたります。なお、メソッド呼出し時にネーミングサービスで求めたサーバアプリケーションのオブジェクトリファレンスとサーバプログラムで例外が発生した場合に例外情報を設定するためにtry-catchブロックを指定します。
処理の記述例を以下に示します。
ODdemo.calculator target; // アプリケーション用オブジェクトリファレンス try { // ODdemo.calculatorクラスへの変換 target = ODdemo.calculatorHelper.narrow(Obj); ODdemo.calculatorPackage.result res = new ODdemo.calculatorPackage.result(); res = target.calculate( a, b ); ... } catch( NumberFormatException e ){ ... // 例外処理 } catch( ODdemo.calculatorPackage.ZEROPARAM e ){ ... // 例外処理 } catch( org.omg.CORBA.SystemException err ){ ... // 例外処理 }
サーバアプリケーションのメソッド呼出しの結果を復帰状態から判断し、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions.Current.commitメソッドを呼び出し、トランザクションをコミットします。トランザクションを異常終了する場合は、CosTransactions.Current.rollbackメソッドを呼び出し、トランザクションをロールバックします。
処理の記述例を以下に示します。
boolean rhuristic; ... rhuristic = true; try { current.commit( rhuristic ); }catch( NoTransaction e) { ... // 例外処理 } ... current.rollback( );
動的起動インタフェースでサーバアプリケーションを呼び出す場合の、クライアントアプリケーションの記述例について説明します。
■初期化
初期化処理として、ORBのオブジェクトリファレンスを取得します。オブジェクトリファレンスを取得するには、初期化メソッドを呼び出します。
記述例を以下に示します。
static org.omg.CORBA.ORB Orb; // ORB用オブジェクトリファレンス public void initialize(){ try { // ORBの初期化処理 Orb = org.omg.CORBA.ORB.init( arg, null ); ... } catch( java.lang.Exception e ){ ... } } // initialize()
■ネーミングサービスのオブジェクトリファレンスの獲得
実行するオブジェクトをネーミングサービスから検索するために、ネーミングサービスのオブジェクトリファレンスを取得します。ネーミングサービスのオブジェクトリファレンスには、CORBAインタフェースのオブジェクトリファレンスの取り出しメソッドを使用します。
処理の記述例を以下に示します。
org.omg.CosNaming.NamingContextExt Cos; // NamingService用オブジェクトリファレンス try { // NamingServiceのオブジェクトリファレンスの取得 org.omg.CORBA.Object _tmpObj = Orb.resolve_initial_references( “NameService” ); Cos = org.omg.CosNaming.NamingContextExtHelper.narrow( _tmpObj ); if( Cos == null ){ ...; } } catch( java.lang.Exception e ){ ... // 例外処理 }
■インタフェースリポジトリのサーバアプリケーション情報の獲得
インタフェースリポジトリには、IDLで定義されたモジュール名、インタフェース名、オペレーション名、パラメタが階層構造で格納されています。インタフェースリポジトリからサーバアプリケーションの情報を獲得する方法について、以下に示します。
インタフェースリポジトリからサーバアプリケーションの情報を取得するためには、InterfaceDefオブジェクトのオブジェクトリファレンスが必要です。InterfaceDefオブジェクトのオブジェクトリファレンスを求めるには、オブジェクト名をパラメタとして、ネーミングサービスからサーバアプリケーションのオブジェクトリファレンスを求めたあと、CORBA_Object_get_interface()メソッドにより、InterfaceDefオブジェクトリファレンスを取得します。
処理の記述例を以下に示します。
try { String NCid = new String( "ODdemo::calculator" ); // オブジェクト名 String NCkind = new String( "" ); // オブジェクトのタイプ // オブジェクト名、タイプの設定 org.omg.CosNaming.NameComponent nc = new org.omg.CosNaming.NameComponent( NCid, NCkind ); org.omg.CosNaming.NameComponent NCo[] = { nc }; //NamingServiceのresolveメソッドを発行 org.omg.CORBA.Object target = Cos.resolve( NCo ); // org.omg.CORBA.InterfaceDefオブジェクトリファレンス取得 org.omg.CORBA.InterfaceDef intf = target._get_interface(); } catch( java.lang.Exception e ) { ... // 例外処理 }
サーバアプリケーションのメソッド名をパラメタとして、CORBA_InterfaceDef_lookup_name()メソッドにより、指定されたメソッドをインタフェースリポジトリから検索します。このメソッドにより、指定したメソッド情報が格納されているOperationDefオブジェクトのオブジェクトリファレンスが通知されます。
処理の記述例を以下に示します。
// メソッドのorg.omg.CORBA.OperationDefオブジェクトリファレンス取得 String name = new String( "calcurate" ); org.omg.CORBA.Contained[] intf_opr = intf.lookup_name( name, -1, org.omg.CORBA.DefinitionKind.dk_Operation, false );
org.omg.CORBA.Contained.describe()メソッドにより、サーバアプリケーションがもっているメソッドのパラメタの情報(パラメタの名前、個数、パラメタの型など)をインタフェースリポジトリから検索します。パラメタとして、org.omg.CORBA.OperationDefオブジェクトリファレンスを指定します。
org.omg.CORBA.ContainedPackage.Description desc = intf_opr[0].describe(); // 指定されたメソッドのパラメタ情報を検索
トランザクションを開始するために、Currentインタフェースのオブジェクトリファレンスを取得し、CosTransactions.Current.beginメソッドを呼び出します。
処理の記述例を以下に示します。
static org.omg.CosTransactions.Current current; // トランザクション開始オブジェクトリファレンス // トランザクション開始インタフェースのオブジェクトリファレンスを獲得 org.omg.CORBA.Object _tmpObj1 = Orb.resolve_initial_references("TransactionCurrent"); current = org.omg.CosTransactions.CurrentHelper.narrow(_tmpObj1); // トランザクション開始メソッドの呼出し current.begin();
org.omg.CORBA.ORB.create_list()メソッドにより、サーバアプリケーションに渡すパラメタを格納するための領域を保持するリストオブジェクトを生成します。このとき、何個のパラメタを格納するかを指定します。結果として、NVListオブジェクトリファレンスが通知されます。
処理の記述例を以下に示します。
org.omg.CORBA.NVList Nvl; // NVList // org.omg.CORBA.ContainedPackage.Description構造体からパラメタ情報構造体の抽出 org.omg.CORBA.Any opeany = desc.value; org.omg.CORBA.OperationDescription c = org.omg.OperationDescriptionHelper.extract( opeany ); org.omg.CORBA.ParameterDescription[] paraseq = c.parameters; // パラメタ情報の抽出 int ParamCount = paraseq.length; // リストオブジェクトの生成 Nvl = Orb.create_list( ParamCount );
org.omg.CORBA.NVList.add_value()メソッドにより、サーバアプリケーションに渡すパラメタをリストオブジェクトに設定します。パラメタとして、サーバアプリケーションのパラメタの名前、値(Any型)およびパラメタの形式を設定します。
処理の記述例を以下に示します。
org.omg.CORBA.NamedValue tmpNam; org.omg.CORBA.Any Anya = Orb.create_any(); Anya.insert_long(a); tmpNam = Nvl.add_value( paraseq[0].name, Anya, org.omg.CORBA.ARG_IN.value ); org.omg.CORBA.Any Anyb = Orb.create_any(); Anyb.insert_long(b); tmpNam = Nvl.value.add_value( paraseq[1].name, Anyb, org.omg.CORBA.ARG_IN.value );
org.omg.CORBA.Object._create_request()メソッドにより、リクエストオブジェクトを作成します。リクエストオブジェクトに対して、サーバオブジェクトのオブジェクトリファレンス、org.omg.CORBA.NVListオブジェクトリファレンス、org.omg.CORBA.NamedValueと呼ぶサーバの処理結果を格納する領域を指定します。結果として、リクエストオブジェクトが返されます。
処理の記述例を以下に示します。
// 復帰パラメタ org.omg.CORBA.Any AnyResult = Orb.create_any(); AnyResult.type(c.result); // 復帰パラメタ格納域 org.omg.CORBA.NamedValue Result = Orb.create_named_value( null, AnyResult, org.omg.CORBA.ARG_OUT.value); String OpName = new String(c.name); // リクエストオブジェクトの生成 org.omg.CORBA.Request Req = target._create_request( null, // context OpName, // メソッド名 Nvl, // 入力パラメタ Result); // 復帰値
サーバアプリケーションに対してリクエストを送信します。リクエストの方法として、以下の方法があります。
同期送信
非同期送信
それぞれについて、以下に示します。
org.omg.CORBA.Request.send_deferred()メソッドにより、サーバアプリケーションを呼び出します。サーバアプリケーションの処理結果は、org.omg.CORBA.Request.get_response()メソッドにより受け取ります。
処理の記述例を以下に示します。
Req.send_deferred(); // 処理の要求 Req.get_response(); // 処理結果の受取り
org.omg.CORBA.Request.get_response()サーバアプリケーションからリクエストが完了していないことが判明した場合、再度org.omg.CORBA.Request.get_response()メソッドを呼び出します。
サーバアプリケーションのメソッド呼出しの結果を復帰状態から判断し、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions.Current.commitメソッドを呼び出し、トランザクションをコミットします。トランザクションを異常終了する場合は、CosTransactions.Current.rollbackメソッドを呼び出し、トランザクションをロールバックします。
処理の記述例を以下に示します。
boolean rhuristic; ... rhuristic = true; try { current.commit( rhuristic ); } catch( NoTransaction e) { ... // 例外処理 } ... current.rollback( );