グローバルトランザクション運用を行うためには、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(CORBA.CORBAException e){ Current.rollback(); … 6 } |
ネーミングサービスからサーバアプリケーションのオブジェクトリファレンスを獲得します。
Currentインタフェースのオブジェクトリファレンスを獲得します。
CosTransactions.Current.beginメソッドでトランザクションの開始を宣言します。
サーバアプリケーションを呼び出します。
サーバアプリケーションの復帰状態を確認して、トランザクションの状態を決定します。トランザクションを正常終了させる場合はCosTransactions.Current.commitメソッドでトランザクションをコミットさせます。
異常が発生した場合は、CosTransactions.Current.rollbackメソッドでトランザクションをロールバックさせます。
クライアントアプリケーションからサーバアプリケーションを呼び出す形態を、以下に示します。
サーバアプリケーションを呼び出し、サーバアプリケーションのメソッドが終了した時点でクライアントアプリケーションに制御が戻ります。
サーバアプリケーションを呼び出し、サーバアプリケーションのメソッドの終了を待たずにクライアントアプリケーションに制御が戻ります。クライアントアプリケーションは任意のタイミングでサーバアプリケーションのメソッドの終了を問い合わせます。
同期型
同期型呼び出しは、クライアントアプリケーションからサーバアプリケーションを呼び出し、そのサーバアプリケーションの処理終了を待ち合わせる呼び出し形態です。同期型の呼び出し形態について、以下に示します。
同期型には、静的起動インタフェース、動的起動インタフェースがあります。静的起動インタフェースは、サーバアプリケーションのメソッド名を指定して呼び出します。動的起動インタフェースは、Requestインタフェースのinvokeメソッドでサーバアプリケーションを呼び出します。詳細は、“リファレンスマニュアル(API編)”を参照してください。また、動的起動インタフェースにおいて、遅延同期送信を行う場合の注意事項を以下に示します。
遅延同期送信の呼び出し元は、その呼び出しの復帰が完了するまでデータベースの操作を禁止します。
遅延同期送信の呼び出し先は、データベースを使用する場合には、複数の呼び出しが同じデータベースにアクセスできません。
遅延同期送信で呼び出されたアプリケーションから、同時に同一のデータベースを操作することはできません。
遅延同期送信で呼び出されたアプリケーションから、異なるデータベースを操作することはできます。
同期型を使用する場合のクライアントアプリケーションの処理論理を、以下に示します。
サーバアプリケーション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.invoke()メソッドにより、サーバアプリケーションを呼び出します。
処理の記述例を以下に示します。
Req.invoke(); |
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()メソッドを呼び出します。
リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA.Request.delete()メソッドにより、リクエストオブジェクトを削除します。処理の記述例を以下に示します。
CORBA.Request.delete(); //リクエストオブジェクトの削除 |
サーバアプリケーションのメソッド呼び出しの結果を復帰状態から判断し、トランザクションの状態を決定します。トランザクションを正常に終了させる場合には、CosTransactions.Current.commitメソッドを呼び出し、トランザクションをコミットさせます。トランザクションを異常で終了させる場合には、CosTransactions.Current.rollbackメソッドを呼び出し、トランザクションをロールバックさせます。処理の記述例を以下に示します。
boolean rhuristic; ... rhuristic = true; try { current.commit( rhuristic ); } catch( NoTransaction e) { ...//例外処理 } ... current.rollback( ); |