• 検索結果がありません。

WebOTXマニュアル

N/A
N/A
Protected

Academic year: 2021

シェア "WebOTXマニュアル"

Copied!
30
0
0

読み込み中.... (全文を見る)

全文

(1)

WebOTX アプリケーション開発ガイド バージョン: 7.1

版数: 初版

リリース: 2007 年 7 月

Copyright (C) 1998 - 2007 NEC Corporation. All rights reserved.

(2)

目次

7. CORBA...3

7.3. Transactionサービス ...3

7.3.1. アプリケーションプログラムを開発する前に...3

7.3.2. IDLファイルの作成...5

7.3.3. クライアントアプリケーションの開発(C++言語)...5

7.3.4. サーバアプリケーションの開発(C++言語)...11

7.3.5. クライアントアプリケーションの開発(Java言語、JavaApplet) ...12

7.3.6. サーバアプリケーションの開発(Java言語)...17

7.3.7. データベースアプリケーションを開発する前に(C++言語) ...17

7.3.8. データベースアプリケーションのプログラミング例(C++言語)...21

(3)

7.CORBA

本章では、WebOTX Developer の機能を使いこなすための詳細な説明を行います。また、WebOTX が提 供する API の利用方法について説明します。

7.3.Transaction サービス

本節では Transaction サービスを使ったアプリケーションプログラムの作成の方法について説明します。ア プリケーションプログラムの作成の説明には、作成の流れにそった説明と実装する機能ごとに分類した説 明とがあります。新規にトランザクションを構築する場合は、作成の流れにそって読むことをお勧めします。 Transaction サービス上のアプリケーションプログラムは、ORB を使ったアプリケーションプログラムと同じ です。ORB を使ったプログラミングの詳細については、プログラミング・開発の章の「Object Broker」を参照 してください。

7.3.1.アプリケーションプログラムを開発する前に

本節では WebOTX Transaction サービス上のアプリケーションプログラムの作成において、必要となる概念 の説明を行います。

WebOTX Transaction サービスのトランザクションモデル

WebOTX Transaction サービスは、CORBA トランザクションサービスにしたがって、トランザクションコンテキ ストを使ってトランザクションの制御・管理を行います。トランザクションコンテキストとは、トランザクションの さまざまな状態を管理する論理的な概念で、 Control オブジェクトに対応します。 アプリケーションプログラムは、WebOTX Transaction サービスが提供するさまざまなインタフェースを利用 してトランザクションコンテキストの状態の更新・参照を行い、トランザクションの動作の制御・管理を行いま す。 トランザクションコンテキストをアプリケーションが動作するスレッドに関連付けることで、アプリケーションは トランザクション内で動作します。トランザクションコンテキストとスレッドとの関連付けには次の方法があり ます。 関連付けの方法 説明 間接的なコンテキスト管理 Current オブジェクトや暗黙の伝播により、WebOTX Transaction サービスがトランザクションコンテキストをスレッ ドに関連付け、管理を行います(一般的にはこちらが利用さ れます)。 直接的なコンテキスト管理 アプリケーションが Control オブジェクトとスレッドとの関連付 け、管理を行います。

WebOTX Transaction サービスでは、WebOTX Transaction サービスを利用したトランザクションプログラム を次の 3 つのトランザクションモデルに分類しています。 モデル 説明 間接的なコンテキスト管理: クライアントトランザクション クライアントプログラムが Current オブジェクトの提供するインタ フェースを使用してトランザクションの管理を行います。 したがって、クライアントプログラムはトランザクショナルクライア ントとなります。 クライアントプログラムはトランザクショナルオブジェクトや、非ト ランザクショナルオブジェクトを呼び出してトランザクション処理を 行います。 OTS1.2 では、OTSPolicy により振る舞いを決定します。 一般的には、サーバプログラムがデータベースを参照・更新する リカバラブルサーバとして動作します。

(4)

クライアントプログラム側にデータベースがあっても、サーバプロ グラム側にデータベースがなくてもかまいません。 間接的なコンテキスト管理: サーバトランザクション サーバプログラムが、Current オブジェクトの提供するインタフェ ースを使用してトランザクションの管理を行います。 クライアントプログラムはトランザクションとは無関係な非トラン ザクショナルクライアントとなります。 このモデルでは、サーバプログラムはトランザクショナルクライア ントとなるか、トランザクションとして通信を行わない単独のオブ ジェクトになります。 したがって、CORBA トランザクションサービスの概念としてはクラ イアントトランザクションと差はありませんが、サーバオブジェクト はマルチスレッドで動作するため、WebOTX Transaction サービ スの管理は変わります。 直接的なコンテキスト管理 アプリケーションが Current オブジェクトを利用しないで、直接 Control オブジェクトを利用してトランザクションコンテキストの管 理を行います。 この場合、WebOTX Transaction サービスはトランザクションコン テキストの伝播を支援しませんので、明示的な伝播が行われま す。 そのため、クライアントプログラム・サーバプログラムの処理の分 担はアプリケーションが自由に設定することができます。

OTSPolicy にもとづく振る舞い

CORBA Transaction サービス 1.1(OTS1.1)では、TransactionalObject インタフェースの継承有無によりトラ ンザクションコンテキストの伝播を行うか否かを決定していましたが、OTS1.2 より POA のポリシーに OTSPolicy を設定することによりトランザクションの振る舞いを設定します。

この POA 上で動作するオブジェクトはこの影響を受けます。

OTSPolicy 値とサーバ側でのトランザクションの振る舞いの関係は以下の表のとおりです。 OTSPolicy Transaction 有りで呼び出し Transaction 無しで呼び出し

REQUIRES トランザクション内で動作 TRANSACTION_REQUIRED 例外 FORBIDS INVALID_TRANSACTION 例外 トランザクション無しで動作 ADAPTS トランザクション内で動作 トランザクション無しで動作

OTS1.1 での TransactionalObject を継承したオブジェクトは、OTSPolicy を ADAPTS とした場合に相当し、 TransactionalObject を継承しないオブジェクトは OTSPolicy に何も設定されず、この場合呼び出し時の Transaction の有無にかかわらずトランザクション無しで動作します。

スレッド処理方針とオブジェクト活性化方針

Object Broker では、アプリケーションの動作に関する処理方針を利用者が決定することができます。 WebOTX Transaction サービスを使ったアプリケーションの開発において、間接的なコンテキスト管理を使 用する場合、スレッドをトランザクションコンテキストに関連付けます。そのため、Object Broker の方針を利 用できない場合があります。 次の表は、方針の利用の可否を示しています。 C++ スレッド処理方針 処理方針 サポート 説明 Resource オブジェクト や Synchronization オ ブジェクトで実装すべ きメソッドについては 「API リファレンスマニ ュアル -CORBA-Transaction サービス」を参照して ください。

(5)

スレッドを使用する ○ プログラマが作成した実装部分をマルチスレッドで実行しま す。 スレッドを使用しない △ プログラマが作成した実装部分は必ずシングルスレッドで処 理されます。トランザクションに参加させるリソースを実装す る Resource オブジェクトやトランザクション完了時のコール バックを実装する Synchronization オブジェクトはマルチスレ ッドで処理するようにしてください。 Java スレッド処理方針 処理方針 サポート 説明 スレッドを使用する ○ プログラマが作成した実装部分をマルチスレッドで実行しま す。 スレッドを使用しない △ プログラマが作成した実装部分は必ずシングルスレッドで処 理されます。トランザクションに参加させるリソースを実装す る Resource オブジェクトやトランザクション完了時のコール バックを実装する Synchronization オブジェクトはマルチスレ ッドで処理するようにしてください。 オブジェクト処理方針 処理方針 サポート 説明 スレッドを使用する ○ 指定されたオブジェクトをマルチスレッドで処理します。スレ ッド処理方針がスレッドを使用する場合のみ有効です。 スレッドを使用しない △ 指定されたオブジェクトをシングルスレッドで処理します。ス レッド処理方針がスレッドを使用する場合のみ有効です。ト ランザクションに参加させるリソースを実装する Resource オ ブジェクトやトランザクション完了時のコールバックを実装す る Synchronization オブジェクトはマルチスレッドで処理する ようにしてください。

7.3.2.IDL ファイルの作成

サーバアプリケーションが提供するインタフェースを IDL 言語を利用して定義します。IDL 言語による定義に より、C++で作成したサーバアプリケーションを Java のクライアントから呼び出すなど、アプリケーションプロ グラムの実装言語を意識することなく通信を行うことができます。 本節では以降のアプリケーションプログラムの開発の説明において利用する IDL 定義について記述しま す。IDL コンパイルの方法については、プログラミング・開発編の「Object Broker」もしくは「WebOTX CORBA アプリケーション」を参照してください。

/* Test.idl */ module Test { interface interop {

void write( in long a, in long b); long read( in long a);

}; };

7.3.3.クライアントアプリケーションの開発(C++言語)

本節では、CORBA トランザクションサービスを利用した C++クライアントアプリケーションプログラムの開発 手順について、「間接的なコンテキスト管理」を利用するケースについて説明します。「直接的なコンテキス

(6)

ト管理」のケースについては、「API リファレンスマニュアル」を参照してください。。 間接的なコンテキスト管理では、Current オブジェクトを使ってトランザクションを管理します。

クライアントアプリケーションプログラムのメイン処理構成

クライアントアプリケーションプログラムのメイン処理部分には、次の処理を記述します。

ORB の初期化

ORB クラスの初期化メソッド(CORBA::ORB_init())を呼び出し、ORB を初期化します。 #include "orb.h" #include "otxscur.h" CORBA::ORB_ptr orb; try{

orb = CORBA::ORB_init(argc, argv, ""); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

トランザクションサービスの初期化

間接的なコンテキスト管理を行うには、はじめに TransactionService クラスの init メソッドを呼び出すことに よりトランザクションサービスを初期化します。トランザクションサービスの初期化は、ユーザプロセスで 1 回 だけ行います。 try{ OTXSCur::TransactionService::init(orb,argc,argv); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

サーバプログラムのオブジェクトリファレンスの取得

サーバアプリケーションプログラム側で生成した実装オブジェクトのリファレンスを取得します。 取得方法としては、(1)名前サービスに登録してあるものを resolve して取得する。(2)文字列化したリファレ ンスを、格納してあるファイルから取り出して string_to_object メソッドを使用して取得する。などが考えられ ます。ここでは(1)の方法を使用した場合について説明します。 Test::interop_var test; // 名前コンテキストの取得 CosNaming::NamingContext_var namectx; try { CORBA::Object_var nmobj = orb->resolve_initial_references("NameService"); namectx = CosNaming::NamingContext::_narrow(nmobj); if (CORBA::is_nil((CosNaming::NamingContext_ptr)namectx)) { return -1; }

} catch (CORBA::Exception &exc) { exc._dump(stderr);

}

// オブジェクトリファレンスの取得 CosNaming::Name objname;

(7)

objname.length(1);

objname[0].id = (const char*)"test"; objname[0].kind = (const char*)""; try {

obj = namectx->resolve(objname); test = Test::interop::_narrow(obj); } catch (CORBA::Exception &exc) { exc._dump(stderr);

}

Current の取得

Current オブジェクトは、プロセスに 1 つだけ存在します。以降 Current オブジェクトが提供するインタフェー スを利用することでトランザクションの動作が可能になります。

Current オブジェクトを入手するには、ORB クラスの resolve_initial_references メソッドを使用します。 CORBA::Object_var obj; CosTransactions::Current_ptr current; try{ obj = orb->resolve_initial_references("TransactionCurrent"); current = CosTransactions::Current::_narrow(obj); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

データベースの登録

トランザクション内で使用するデータベースを必要となる数だけ登録します。 クライアントアプリケーションでデータベースを使用する場合は、リカバリサーバを起動し、Transaction サー ビス運用管理ツール、もしくはコマンドを使用してデータベースの登録を行います。詳細については、運用 編の付録「Transaction サービス(リカバリサーバ利用時)」を参照してください。 OTXSCur::TransactionService trans; try{ trans.__register("ORACLE"); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

データベースの接続

トランザクション内で利用するデータベースと接続します。 try{ trans.__open(); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

トランザクションの開始

トランザクションを開始します。Current オブジェクトの begin メソッドをコールすることで、新規トランザクショ ンが生成されます。トランザクションが既に開始されている場合にトランザクションを開始すると、サブトラン ザクションが生成されます。 try{

(8)

current->begin(); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

サーバプログラムの呼び出し

「サーバプログラムのオブジェクトリファレンスの取得」で取得したリファレンスを使用してサーバプログラム の呼び出しを実施します。メソッドは、IDL で定義されたインタフェースをもとにします。 トランザクションコンテキストは、暗黙的にサーバプログラムに伝播されます。 try{ test->write(a, b); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

トランザクションの終了

トランザクション処理が終わったら、トランザクションを終了します。Current オブジェクトの commit メソッド または rollback メソッドをコールすることでトランザクションは終了します。コミットまたはロールバックが完 了すると、トランザクションは破棄されます。サブトランザクションが終了した場合、そのサブトランザクショ ンを開始する前のトランザクション(親トランザクション)が再開されます。commit の引数には、2 フェーズコミ ットの完了を待ち合わせるか、待ち合せないかを指定します。 次のトランザクションを開始する場合には、再び Current オブジェクトの begin メソッドを呼び出します。 try{ current->commit(CORBA_TRUE); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; } または try{ current->rollback(); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

トランザクションサービスの停止

トランザクションサービスを停止するために、TransactionService クラスの term メソッドをコールします。デ ータベース処理を開始していた場合には、トランザクションサービスを終了させる前にデータベースの終了 処理をコールします。以降トランザクションサービスを開始しない限り、トランザクション処理を行うことはで きません。 try{ OTXSCur::TransactionService::term(); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

(9)

クライアントアプリケーションプログラムのコンパイルとリンク

アプリケーションプログラムのコンパイル、リンクを実行する前に次のことを確認します。

Windows 版の場合

・ コンパイル ヘッダのパスとして、%WebOTX インストールフォルダ%\ObjectBroker\namespace\include と、%WebOTX インストールフォルダ%\TS\include を追加します。 ・ リンク

ライブラリのパスとして、%WebOTX インストールフォルダ%\ObjectBroker\namespace\lib と、%WebOTX インストールフォルダ%\TS\lib を追加します。

ライブラリとしては以下を追加します。

[Visual Studio .NET 2003 の場合] notscu74.lib, nosp906.lib [Visual Studio 2005 の場合] notscu76.lib, nosp908.lib [64bit(EM64T)版の場合] notscu75.lib, nosp907.lib

HP-UX(IPF LP64)版の場合

・ コンパイル コンパイルオプションに、-DOB_HPUX_KT +DD64 -mt -I/opt/WebOTX/TS/include -I/usr/lib/ObjectSpinner/namespace/include を追加します。 ・ リンク リンク時のオプションとして、+DD64, -mt に加え、-lnotscur を追加します。

Linux 版の場合

・ コンパイル

コンパイルオプションに、-D_GNU_SOURCE -D_REENTRANT -I/opt/WebOTX/TS/include -I/usr/lib/ObjectSpinner/namespace/include を追加します。

・ リンク

リンク時のオプションとして、-lnotscur を追加します。

クライアントアプリケーションプログラムの実行

作成したアプリケーションプログラムを実行する前に次のことを確認してください。

・ Proxy RCS(Proxy Recovery Coordination Server)、もしくはリカバリサーバと Object Broker が動作して いる

クライアントアプリケーションでトランザクションを開始するためには、トランザクションを管理するサーバで ある、Proxy RCS、もしくはリカバリサーバと Object Broker があらかじめ動作している必要があります。 動作していない場合は、運用管理ツール、あるいは運用管理コマンドを利用して起動します。 これらの詳細については、WebOTX 運用編(運用操作)、運用編の付録「Transaction サービス(リカバリサー バ利用時)」を参照してください。

その他のトランザクション機能

ここまでの説明で簡単な間接的なコンテキスト管理のプログラムを作成することが可能です。本節では、間 接的なコンテキスト管理のその他機能について説明します。

rollback_only(ロールバックのマーク)

(10)

トランザクション中に障害があったとき、トランザクション生成者はロールバックを行えば良いですが、トラン ザクション生成者でないとロールバックを発行できません。このような場合にトランザクションが最終的には 必ずロールバックされるように設定することができます。トランザクションがロールバックするように設定す るには、Current インタフェースの rollback_only メソッドをコールします。 try{ current->rollback_only(); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

get_status(トランザクション状態の取得)

トランザクションの状態を取得するには、Current インタフェースの get_status メソッドをコールします。 CosTransactions::Status status; try{ status = current->get_status(); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

get_transaction_name(トランザクション識別名の取得)

トランザクションを識別するための文字列を取得するには、Current インタフェースの get_transaction_name メソッドをコールします。 char* txname; try{ txname = current->get_transaction_name(); }catch(CORBA::exception& exc){ exc._dump(stderr); }

set_timeout(トランザクションタイムアウト時間の設定)

トランザクションのタイムアウト時間を設定するには、Current インタフェースの set_timeout メソッドをコール します。トランザクションの処理が無限ループに入ってしまった場合でも、このインタフェースを利用すること で、指定秒数経過後にロールバック処理が自動的に実行されトランザクション処理が戻ります。 set_timeout はトランザクションを開始する begin メソッドの前にコールします。 try{ current->set_timeout(30); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

get_timeout(トランザクションタイムアウト時間の取得)

トランザクションのタイムアウト時間を取得するには、Current インタフェースの get_timeout メソッドをコール します。 int timeout; try{ timeout = current->get_timeout(); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

(11)

get_control(Control オブジェクトの取得)

Control オブジェクトを取得するには、Current インタフェースの get_control メソッドをコールします。 Control オブジェクトを使用して明示的なトランザクション処理を行う場合に使います。 Control オブジェクトの機能については、直接的なコンテキスト管理またはリファレンスマニュアルを参照し てください。 CosTransactions::Control_ptr control; try{ control = current->get_control(); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

suspend(トランザクションのサスペンド)

Current オブジェクトは、トランザクションをアプリケーション内で動作しているスレッドと対応させて管理して います。そのスレッドからトランザクションコンテキストを切り離す場合には、Current インタフェースの suspend メソッドをコールします。 resume またはトランザクションを新たに開始するまで、スレッドはトランザ クションと関連を持ちません。 CosTransactions::Control_ptr control; try{ control = current->suspend(); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

resume(トランザクションのレジューム)

指定された Control オブジェクトが示すトランザクションをスレッドに関連付けるには、Current インタフェー スの resume メソッドをコールします。suspend したトランザクションを再開する場合や、直接的なコンテキス ト管理で入手したトランザクションを間接的なコンテキスト管理で利用する場合に使います。 try{ current->resume(control); }catch(CORBA::Exception& exc){ exc._dump(stderr); }

7.3.4.サーバアプリケーションの開発(C++言語)

本節では、CORBA トランザクションサービスを利用した C++サーバアプリケーションプログラムの開発手順 について、「間接的なコンテキスト管理」を利用するケースについて説明します。「直接的なコンテキスト管 理」のケースについては、「API リファレンスマニュアル」を参照してください。 間接的なコンテキスト管理では、Current オブジェクトを使ってトランザクションを管理します。 サーバアプリケーションは WebOTX 上で動作させることになるため、IDL ファイルの作成やアプリケーション のビルド、WebOTX への登録などは一般的な WebOTX 上のアプリケーションを開発を行う際と同じです。こ の詳細に関しては、プログラミング・開発の章の「WebOTX CORBA アプリケーション」を参照してください。 なお、WebOTX CORBA アプリケーションで Transaction サービスを利用する場合には運用管理ツールでの 設定が必要となります。詳細については、WebOTX 運用編(運用操作)を参照してください。

以下では、間接的なコンテキスト管理に必要な Current オブジェクトのサーバアプリケーションでの取得方 法について説明します。

(12)

たものと同じですのでそちらを参照してください。

またクライアントアプリケーション作成時に流れで説明した ORB の初期化、Transaction サービスの初期化 については WebOTX のアプリケーション起動時に自動的に実行され、データベースの登録、開始について も運用管理ツールで指定することにより自動的に実行されます。

Current の取得

Current オブジェクトを取得するためにはまず ORB オブジェクトを取得する必要があります。ORB オブジェ クトは TPSGetORB(orb)により取得します。Current オブジェクトは、ORB クラスの resolve_initial_references メソッドを使用して取得します。 CORBA::ORB_ptr orb; CORBA::Object_var obj; CosTransactions::Current_ptr current; try{ TPSGetORB(orb); obj = orb->resolve_initial_references("TransactionCurrent"); current = CosTransactions::Current::_narrow(obj); }catch(CORBA::Exception& exc){ exc._dump(stderr); return -1; }

7.3.5.クライアントアプリケーションの開発(Java 言語、JavaApplet)

本節では、CORBA トランザクションサービスを利用した Java クライアントアプリケーションプログラムの開 発手順について、「間接的なコンテキスト管理」を利用するケースについて説明します。「直接的なコンテキ スト管理」のケースについては、「API リファレンスマニュアル」を参照してください。。 間接的なコンテキスト管理では、Current オブジェクトを使ってトランザクションを管理します。

クライアントアプリケーションプログラムのメイン処理構成

クライアントアプリケーションプログラムのメイン処理部分には、次の処理を記述します。

ORB の初期化

ORB クラスの初期化メソッド init を呼び出し、ORB を初期化します。 Java 言語の場合

import org.omg.CORBA.*;

public static void main(String args[]) { try {

// Initialize ORB.

ORB orb = ORB.init(args, null); } catch (Exception e) { e.printStackTrace(); } …… } JavaApplet の場合 import org.omg.CORBA.*; …… try {

(13)

// Initialize ORB.

ORB orb = ORB.init(Applet, null); } catch (Exception e) { e.printStackTrace(); } …… }

サーバプログラムのオブジェクトリファレンスの取得

サーバアプリケーションプログラム側で生成した実装オブジェクトのリファレンスを取得します。 取得方法としては、(1)名前サービスに登録してあるものを resolve して取得する。(2)文字列化したリファレ ンスを、格納してあるファイルから取り出して string_to_object メソッドを使用して取得する。などが考えられ ます。ここでは(1)の方法を使用した場合について説明します。 Test.interop sv; try { // 名前コンテキストの取得 org.omg.CORBA.Object o = orb.resolve_initial_references("NameService"); NamingContext ns = NamingContextHelper.narrow(o); // オブジェクトリファレンスの取得

NameComponent nc = new NameComponent("test", ""); NameComponent ncseq[] = {nc}; sv = Test.interopHelper.narrow(ns.resolve(ncseq)); } catch (Exception e) { e.printStackTrace(); }

Current オブジェクトの取得

Current オブジェクトは、プロセスに 1 つだけ存在します。これによりトランザクションサービスが初期化さ れ、以降 Current オブジェクトが提供するインタフェースを利用することでトランザクションの動作が可能に なります。

Current オブジェクトを入手するには、ORB クラスの resolve_initial_references メソッドを使用します。 org.omg.CosTransactions.Current cur; try { cur = (Current)orb.resolve_initial_references("TransactionCurrent"); } catch (Exception e) { e.printStackTrace(); }

トランザクションの開始

トランザクションを開始します。Current オブジェクトの begin メソッドをコールすることで、新規トランザクショ ンが生成されます。トランザクションが既に開始されている場合にトランザクションを開始すると、サブトラン ザクションが生成されます。 try { cur.begin(); } catch (Exception e) { e.printStackTrace(); }

サーバプログラムの呼び出し

(14)

「サーバプログラムのオブジェクトリファレンスの取得」で取得したリファレンスを使用してサーバプログラム の呼び出しを実施します。メソッドは、IDL で定義されたインタフェースをもとにします。 トランザクションコンテキストは、暗黙的にサーバプログラムに伝播されます。 try { sv.write(a, b); } catch (Exception e) { e.printStackTrace(); }

トランザクションの終了

トランザクション処理が終わったら、トランザクションを終了します。Current オブジェクトの commit メソッド または rollback メソッドをコールすることでトランザクションは終了します。コミットまたはロールバックが完 了すると、トランザクションは破棄されます。サブトランザクションが終了した場合、そのサブトランザクショ ンを開始する前のトランザクション(親トランザクション)が再開されます。commit の引数には、2 フェーズコミ ットの完了を待ち合わせるか、待ち合せないかを指定します。 次のトランザクションを開始する場合には、再び Current オブジェクトの begin メソッドを呼び出します。 try { cur.commit(true); } catch (Exception e) { e.printStackTrace(); } または try { cur.rollback(); } catch (Exception e) { e.printStackTrace(); }

クライアントアプリケーションプログラムのコンパイルとリンク

アプリケーションプログラムのコンパイルを実行する classpath に以下のクラスが設定されていることを確認 してください。 ・ Transaction サービスのクラスである、wots71.jar (格納場所:%WebOTX インストールフォルダ%\TS\javalib)

・ Object Broker のクラスである、ospiorb50.jar, jsocks.jar, ospiname50.jar(名前サービス利用時) (格納場所:%WebOTX インストールフォルダ%\ObjectBroker\lib) ・ DataSource のクラスである、wojdbc61.jar (格納場所:%WebOTX インストールフォルダ%\lib)

クライアントアプリケーションプログラムの実行

クライアントアプリケーションプログラム実行時にはコンパイル時のクラスパスに加え以下を設定してくださ い。 ・ J2EE のインタフェース定義である、j2ee.jar (格納場所:%WebOTX インストールフォルダ%\lib) ・ WebOTX のランタイムのクラスである、wosv-rt.jar (格納場所:%WebOTX インストールフォルダ%\lib) 実行時のプロパティとして以下を追加してください。 プロパティ名:org.omg.CORBA.ORBInitRef 値:TransactionCurrent=ospiref:jp.co.nec.WebOTX_S.OTXSCur.CurrentFactory

(15)

作成したアプリケーションプログラムを実行する前に次のことを確認してください。

・ Proxy RCS(Proxy Recovery Coordination Server)、もしくはリカバリサーバと Object Broker が動作して いる

クライアントアプリケーションでトランザクションを開始するためには、トランザクションを管理するサーバで ある、Proxy RCS、もしくはリカバリサーバと Object Broker があらかじめ動作している必要があります。 動作していない場合は、運用管理ツール、あるいは運用管理コマンドを利用して起動します。 これらの詳細については、WebOTX 運用編(運用操作)、運用編の付録「Transaction サービス(リカバリサー バ利用時)」を参照してください。

その他のトランザクション機能

ここまでの説明で簡単な間接的なコンテキスト管理のプログラムを作成することが可能です。本節では、間 接的なコンテキスト管理のその他機能について説明します。

rollback_only(ロールバックのマーク)

トランザクション中に障害があったとき、トランザクション生成者はロールバックを行えば良いですが、トラン ザクション生成者でないとロールバックを発行できません。このような場合にトランザクションが最終的には 必ずロールバックされるように設定することができます。トランザクションがロールバックするように設定す るには、Current インタフェースの rollback_only メソッドをコールします。 try { cur.rollback_only(); } catch (Exception e) { e.printStackTrace(); }

get_status(トランザクション状態の取得)

トランザクションの状態を取得するには、Current インタフェースの get_status メソッドをコールします。 CosTransactions.Status status; try { status = cur.get_status(); } catch (Exception e) { e.printStackTrace(); }

get_transaction_name(トランザクション識別名の取得)

トランザクションを識別するための文字列を取得するには、Current インタフェースの get_transaction_name メソッドをコールします。 String txname; try { txname = cur.get_transaction_name(); } catch (Exception e) { e.printStackTrace(); }

set_timeout(トランザクションタイムアウト時間の設定)

トランザクションのタイムアウト時間を設定するには、Current インタフェースの set_timeout メソッドをコール します。トランザクションの処理が無限ループに入ってしまった場合でも、このインタフェースを利用すること で、指定秒数経過後にロールバック処理が自動的に実行されトランザクション処理が戻ります。

(16)

set_timeout はトランザクションを開始する begin メソッドの前にコールします。 try { cur.set_timeout(30); } catch (Exception e) { e.printStackTrace(); }

get_timeout(トランザクションタイムアウト時間の取得)

トランザクションのタイムアウト時間を取得するには、Current インタフェースの get_timeout メソッドをコール します。 int timeout; try { timeout = cur.get_timeout(); } catch (Exception e) { e.printStackTrace(); }

get_control(Control オブジェクトの取得)

Control オブジェクトを取得するには、Current インタフェースの get_control メソッドをコールします。 Control オブジェクトを使用して明示的なトランザクション処理を行う場合に使います。 Control オブジェクトの機能については、直接的なコンテキスト管理またはリファレンスマニュアルを参照し てください。 org.omg.CosTransactions.Control control; try { control = cur.get_control(); } catch (Exception e) { e.printStackTrace(); }

suspend(トランザクションのサスペンド)

Current オブジェクトは、トランザクションをアプリケーション内で動作しているスレッドと対応させて管理して います。そのスレッドからトランザクションコンテキストを切り離す場合には、Current インタフェースの suspend メソッドをコールします。 resume またはトランザクションを新たに開始するまで、スレッドはトランザ クションと関連を持ちません。 org.omg.CosTransactions.Control control; try { cur.suspend(); } catch (Exception e) { e.printStackTrace(); }

resume(トランザクションのレジューム)

指定された Control オブジェクトが示すトランザクションをスレッドに関連付けるには、Current インタフェー スの resume メソッドをコールします。suspend したトランザクションを再開する場合や、直接的なコンテキス ト管理で入手したトランザクションを間接的なコンテキスト管理で利用する場合に使います。 try { cur.resume(control); } catch (Exception e) { e.printStackTrace(); }

(17)

7.3.6.サーバアプリケーションの開発(Java 言語)

本節では、CORBA トランザクションサービスを利用した Java サーバアプリケーションプログラムの開発手 順について、「間接的なコンテキスト管理」を利用するケースについて説明します。「直接的なコンテキスト 管理」のケースについては、「API リファレンスマニュアル」を参照してください。。 間接的なコンテキスト管理では、Current オブジェクトを使ってトランザクションを管理します。 サーバアプリケーションは WebOTX 上で動作させることになるため、IDL ファイルの作成やアプリケーション のビルド、WebOTX への登録などは一般的な WebOTX 上のアプリケーションを開発を行う際と同じです。こ の詳細に関しては、プログラミング・開発の章の「WebOTX CORBA アプリケーション」を参照してください。 なお、WebOTX CORBA アプリケーションで Transaction サービスを利用する場合には運用管理ツールでの 設定が必要となります。詳細については、WebOTX 運用編(運用操作)を参照してください。 以下では、間接的なコンテキスト管理に必要な Current オブジェクトのサーバアプリケーションでの取得方 法について説明します。 取得した Current オブジェクトの利用方法については「クライアントアプリケーションの開発(Java)」で説明し たものと同じですのでそちらを参照してください。 またクライアントアプリケーション作成時に流れで説明した ORB の初期化については WebOTX のアプリケ ーション起動時に自動的に実行されます。

Current の取得

Current オブジェクトを取得するためにはまず ORB オブジェクトを取得する必要があります。ORB オブジェ クトは WoServerWrapper.TPSGetORB()により取得します。Current オブジェクトは、ORB クラスの resolve_initial_references メソッドを使用して取得します。 org.omg.CORBA.ORB orb; org.omg.CosTransactions.Current cur; try { orb = jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper.TPSGetORB(); cur = (Current)orb.resolve_initial_references("TransactionCurrent"); } catch (Exception e) { e.printStackTrace(); }

7.3.7.データベースアプリケーションを開発する前に(C++言語)

本節では、Transaction サービスを利用した C++言語のデータベースアプリケーションプログラムの開発に おいて、必要となる概念の説明を行います。

Transaction サービスでは Oracle データベースと Microsoft SQL Server、IBM WebSphere MQ の C++(C) 言語のインタフェースをサポートしています。 これらのデータベースとの間では、X/Open XA インタフェー スを使用してグローバルトランザクションの制御を行っています。グローバルトランザクションは、1つ以上 のトランザクションブランチから成り立っています。特に、そのトランザクションブランチの制御について理解 して頂く必要があります。

トランザクションブランチについて

X/Open 分散トランザクション処理では、アプリケーションは、トランザクションブランチ内でトランザクション 処理(SQL 命令)を実行することで「グローバルトランザクション」に参加します。1つのグローバルトランザ クション内で作成されるトランザクションブランチ間の関係には、「疎結合」と「密結合」があります。 疎結合と密結合では、トランザクションブランチ間の動作において、次のような違いがあります。

(18)

動作 疎結合での動作 密結合での動作 SQL 命令実行時の データ共有可否 トランザクションブランチ間では、 SQL 命令の実行時に表ロックや 行ロックによる排他が行われま す。このため、同じテーブルなど の資源を共有することはできま せん。 トランザクションブランチ間では、SQL 命令の実行時に表ロックや行ロックに よる排他が行われません。このため、 同じテーブルなどの資源を共有するこ とができます。更新結果は、トランザク ションブランチ間で引き継がれます。 SQL 命令実行時に デッドロックが発生 する可能性の有無 あります。 ありません。 密結合での並列動作について

Oracle や IBM WebSphere MQ を利用する場合、密結合のトランザクションブランチ間では、トランザクション ブランチが順番に1つずつ動作します。このため、複数のプロセスやスレッドから同じデータを同時に更新 することで、データを破壊してしまう恐れはありません。 Microsoft SQL Server を利用する場合は、密結合のトランザクションブランチ間で、トランザクションブランチ を同時並行して動作させることができます。このため、複数のプロセスやスレッドから同じデータを同時に 更新すると、データを破壊してしまう恐れがありますが、同じグローバルトランザクションに参加する CORBA のアプリケーションオブジェクト間では、メソッド呼び出しが順番に行われるため、データを破壊す るようなことはありません。 疎結合での例外の動作について 疎結合のトランザクションブランチ間では、本来、同じテーブルなどの資源を共有することはできませんが、 Oracle データベースでは、デフォルトの動作の場合、疎結合のトランザクションブランチ間で同じテーブル にアクセスできます。オープン文字列中の Loose_Coupling パラメータに true を指定した場合は、疎結合のト ランザクションブランチ間で同じテーブルにアクセスできなくなります。

トランザクションブランチの開始および終了方法

トランザクションブランチの開始・終了方法には次のものがあります。 動作 開始・終了方法 説明 新規作成 トランザクションブランチを新規に作成します。 連結 以前終了したトランザクションブランチに参加します。 開始 再開 以前中断されたトランザクションブランチに参加します。 正常終了 トランザクションブランチを正常終了します。 中断 トランザクションブランチを一時的に中断します。 終了 結合移行 トランザクションブランチを他のスレッドに移行するために、一時的に 中断します。 グローバルトランザクションに最初に参加する場合、トランザクションブランチを新規作成します。トランザク ションブランチに対応する処理が終了するとトランザクションブランチを正常終了します。 正常終了したトランザクションブランチを再度実行する場合は、トランザクションブランチに連結します。連 結したトランザクションブランチについても対応する処理が終了すると正常終了します。 トランザクションブランチを終了する時に中断させることができます。中断されたトランザクションブランチは 同一のスレッド上で再開しなければなりません。この時、中断ではなく結合移行を行うと、トランザクション ブランチを別のスレッドで再開させることができます。

トランザクションブランチの開始および終了契機

Transaction サービスでは、次の契機でトランザクションブランチを開始および終了します。 契機 開始・終了方法 開始契機 トランザクションの開始 新規作成

(19)

Current:: begin() サーバメソッドの呼び出し開始直前 新規作成: 1 回目の呼び出し 連結: 2 回目以降の呼び出し 再開: 結合移行指定時 メソッド呼び出しの応答受信直後 再開 トランザクションの再開 Current::resume() 再開 トランザクションの終了 Current::commit()または rollback() 正常終了 サーバメソッド終了直後 正常終了: 通常動作 中断: 中断指定時 結合移行: 結合移行指定時 サーバメソッド呼び出しの要求送信直前 中断: 通常動作 結合移行: 結合移行指定時 終了契機 トランザクションの中断 Current::suspend() 中断: 通常動作 結合移行: 結合移行指定時 新規作成の契機が2つあり、これにより、異なるプロセスで動作するクライアント、サーバオブジェクトごと に、ブランチ識別子が異なる、別のトランザクションブランチが作成されます。それらのトランザクションブラ ンチ間の関係は、疎結合となります。 サーバオブジェクトが同一トランザクション内で 2 回目以降に呼び出された場合は、作成済みのトランザク ションブランチと連結します。その場合のトランザクションブラン置換の関係は、密結合となります。 異なるプロセス上で動作するサーバオブジェクトを呼び出すと、トランザクションブランチは中断されます。 また、サーバオブジェクトから呼び出しが戻ってくるとトランザクションブランチは再開されます。これに対し て、同一プロセス内のサーバオブジェクトの呼び出しはトランザクションブランチの状態を変更しません。こ の場合、呼び出し元と呼び出し先のサーバオブジェクトは同一のトランザクションブランチを共有します。 結合移行を使うと、異なるスレッド間で同一のトランザクションブランチを共有することができます。この場 合、サーバオブジェクトを呼び出すと、サーバメソッドの終了直後に結合移行が行われ、同一トランザクショ ン内で再度サーバオブジェクトが呼び出された場合に、どのスレッド上で動作してもトランザクションブラン チが再開されます。

サブトランザクションの動作

X/Open 分散トランザクション処理にはサブトランザクションという概念がなく、仕様の規定もありません。 Transaction サービスでは、独自にサブトランザクションを新たなグローバルトランザクションにマッピングし ています。したがって、親トランザクションとサブトランザクションの間では、データベースのデータを共有す ることができません。 サブトランザクションのコミットは、親トランザクションのコミットと連動して実行されま すので、データの一貫性を保つことができます。

データベースとの接続

データベースに対してトランザクションを実行する前に、XA インタフェースを利用して、データベースとの接 続を行う必要があります。Transaction サービスでは、そのための API を提供しています。 WebOTX のアプリケーションサーバでは、そのデータベースとの接続を自動的に行います。このため、アプ リケーションサーバ上で動作するアプリケーションでは、Transaction サービスが提供するデータベースと の接続を行うための API を呼び出す必要はありません。 単独で動作するアプリケーションでは、次のいずれかのインタフェースを利用してデータベースとの接続を

(20)

行ってください。 詳細は、「API リファレンスマニュアル」の「5. CORBA」の「6. Transaction サービス」を参照 してください。 TXAPI X/Open の TX インタフェースライクな関数インタフェースです。主に動作スレッドを特定できるクライアントア プリケーションで使用します。アプリケーションは、プロセス毎にデータベース識別名を登録します。また、 スレッド毎にデータベースとの接続を行います。 TransactionService インタフェース TransactionService インタフェースは、アプリケーションプロセス内で Transaction サービスの初期化を行う ためのクラスインタフェースです。TXAPI の関数をラップしたメソッドを提供します。アプリケーションは、プロ セス毎にデータベース識別名を登録します。また、スレッド毎にデータベースとの接続を行います。

トランザクションブランチ内の動作

アプリケーションでは、トランザクションブランチ内でデータベースにアクセスすることでグローバルトランザ クションに参加します。グローバルトランザクションを中断(Current::suspend()呼び出し)すると、トランザクシ ョンブランチも中断されます。同様に、他のプロセスのサーバメソッド呼び出しを行った場合もトランザクショ ンブランチは中断されます。 トランザクションブランチが中断された後では、トランザクションに参加しているデータベースに対するアクセ スは失敗します。トランザクションブランチが中断している場合も、ローカルトランザクションとして動作させ ているデータベースに対するアクセスは問題なく行えます。 トランザクションの中断後に再開した場合、中断前の状態から SQL カーソルなどの資源が引き継がれるか どうかはデータベースに依存します。SQL カーソルの再設定が必要なデータベースがほとんどです。デー タベースのマニュアルを参照して確認してください。 CosTransactions::Current_ptr current; current->begin(); // トランザクションの開始 current->suspend(); // トランザクションの中断 // ここではグローバルトランザクションに参加していない current->resume(); // トランザクションの再開 // ここで SQL カーソルが引き継がれるかはデータベース依存 サーバのメソッド呼び出し // トランザクションを中断後、再開 // ここで SQL カーソルが引き継がれるかはデータベース依存 current->commit(CORBA_TRUE); // トランザクションのコミット サーバアプリケーションは、クライアントから呼び出されたメソッドが終了する度にトランザクションから切り 離された状態になります。このため、通常は、サーバアプリケーションのメソッド間で SQL カーソルなどの資 源を引き継ぐことはできません。一般に、各メソッドの先頭で SQL カーソルなどの資源を再設定する必要が あります。

Microsoft SQL Server でのエンリストについて

エンリストとは、データベースアクセス用のハンドルをトランザクションに関連付ける Microsoft SQL Server 固有の操作です。 エンリストは、データベースアクセス用のハンドル毎に行う必要があります。1 つのハンドルは同時に1つの トランザクションに対してしかエンリストすることができません。エンリストを行うと、エンリストされたトランザ クションがコミットまたはロールバックされるまで、そのハンドルを次のトランザクションにエンリストすること はできません。 トランザクション実行中に他のトランザクションにエンリストしようとすると、エンリスト操作は実行中のトラン ザクションが完了するまで待ち合せます。このため、データベースとの接続を1つしか持たないサーバアプ リケーションでは、複数のトランザクションを同時に実行することはできません。 複数のトランザクションを 同時に実行するためには、トランザクション毎にデータベースアクセス用の接続を行う必要があります。 また、同時に 1 つのトランザクションにしかエンリストできないため、同一トランザクション内で複数のメソッド にまたがって処理を行う場合には、ハンドルがエンリスト済みかどうかを確認する必要があります。

(21)

Microsoft SQL Server でのコネクション管理

Microsoft SQL Server を使ったトランザクションシステムで複数のクライアントからの要求を容易に同時処 理できるように、Transaction サービスではコネクション管理機能を提供しています。 コネクション管理機能には次の 3 つの機能があります。 コネクションのプール管理 データベースアクセス用のコネクションをプール管理することができます。

アプリケーションでは、プールされているコネクションがない場合に、Microsoft SQL Server の API を利用し てコネクションを新規に開設し、エンリストした後で、作成したコネクションを Transaction サービスに登録し ます。 登録されたコネクションはアプリケーションオブジェクト毎、かつ、トランザクション毎にプール管理されま す。トランザクションが完了した際には、コネクションプールに返却されます。このため、アプリケーション は、適切な排他制御のもと、コネクションを再利用することができます。 コネクションは、同時実行したトランザクションの数だけプールされます。 いったん登録されたコネクション は、データベースを終了するまで有効ですので、複数回のトランザクションで再利用することができ、データ ベースとの接続および切断に要する時間を節約することができます。 プールされているコネクションは、データベースとの切断処理時に自動的に解放されます。 コネクションの自動切断 コネクションのプール管理を行わない場合は、トランザクションにエンリストされたコネクションを、トランザク ション完了後に解放する必要があります。 クライアント制御トランザクションのように、サーバアプリケーションでのトランザクション終了契機がわから ない場合に、この機能を使用してコネクションを自動的に切断します。 エンリスト要否の問い合わせ 同一トランザクション内でメソッドが複数回呼び出されるような場合に、アプリケーションオブジェクトからエ ンリストを実施すべきかどうかを問い合わせることができます。 コネクション管理機能を利用するためには、Microsoft SQL Server のコネクション管理インタフェースである RmSql インタフェースを利用してください。 RmSql インタフェースには、次の関数があります。 関数名 説明 is_new_sqlsession() 同一トランザクション内で既にハンドルがエンリストされているかどうかを 問い合わせます。 get_sqlsession() is_new_sqlsession()の結果、エンリスト実施済みの場合に、既にトランザク ションに登録済みのハンドルを取得します。 エンリスト実施未の場合は、コネクションプールに登録されているハンドル を取得します。 register_sqlsession() 新規にデータベース接続ハンドルをトランザクションに登録します。引数 で、コネクションをプールするか、自動切断するかを指定します。 RmSql インタフェースの 詳細は、「API リファレン スマニュアル」の、「5. CORBA」の、「6. Transaction サービス」を 参照してください。

7.3.8.データベースアプリケーションのプログラミング例(C++言語)

本節では、CORBA トランザクションサービスを利用した C++言語のデータベースアプリケーションのプログ ラミング例について説明します。

Transaction サービスでは Oracle データベースと Microsoft SQL Server、IBM WebSphere MQ の C++(C) 言語のインタフェースをサポートしています。 これらのデータベースとの間では、X/Open XA インタフェー スを使用してグローバルトランザクションの制御を行っています。データベース固有の情報については、各 データベースのマニュアルで内容を確認してください。 Java 言語のアプリケーションプログラムからデータベースにアクセスする場合は、「プログラミング・開発 (J2EE 編その 2)」の「JDBC アプリケーション」を参照してください。

OraclePro*C/C++のプログラミング

Pro*C/C++を使用して、Oracle データベースへのアクセスを行うためのプログラミング例について説明しま す。Pro*C/C++では、SQL 命令を記述した pc ファイルから、Oracle のプリコンパイラを使用して C または C++のソースを生成します。その pc ファイルに、プログラミング例のような記述を行います。 なお、この例では、Pro*C/C++のエラー処理を省略しています。詳細については、Oracle のリファレンスを

(22)

参照してください。

Oracle Pro*C/C++でのグローバルトランザクションの実行例

グローバルトランザクションを実行するためには、次の例のように記述します。データベースとの接続処理 は不要です。

EXEC SQL BEGIN DECLARE SECTION; // ホスト変数の宣言

DB_NAME CHARACTER(16); long accountno; long balance;

EXEC SQL END DECLARE SECTION; int actno, bal;

CosTransactions::Current_ptr current; SET DB_NAME = ‘ORCL’;

try { //グローバルトランザクションを開始 current->begin();

} catch( CORBA::Exception& exc ){ return -1;

}

accountno = actno; balance = bal; //SQL 命令の実行

EXEC SQL AT :DB_NAME UPDATE a_account

SET BALANCE = :balance WHERE ACCOUNTNO = :accountno; try { //グローバルトランザクションをコミット

current->commit(CORBA_TRUE); } catch( CORBA::Exception& exc ){ return -1;

}

・ XA インタフェースでの接続を利用する場合、グローバルトランザクションとローカルトランザ クションのどちらの場合も、次の SQL 命令は使用できません。

CREATE TABLE などの DDL SQL 文

トランザクションを完了させる EXEC SQL ROLLBACK WORK と EXEC SQL COMMIT WORK、EXEC SQL ROLLBACK WORK RELEASE、EXEC SQL COMMIT WORK RELEASE 文

その他、SET TRANSACTION READ ONLY、READ、WRITE、USE ROLLBACK SEGMENT SQL 文

・ マルチスレッド動作を行う場合、次の SQL 命令は使用できません。 EXEC SQL ALLOCATE と EXEC SQL USE 文

・ カーソルは、トランザクションを完了させる前にクローズしてください。 ・ トランザクションブランチ間で、カーソルやグローバルパッケージ変数を共有することはでき ません。このため、1つのグローバルトランザクション内で、サーバアプリケーションのメソッ ドを複数回呼び出す場合には、メソッドが呼び出される度にカーソルやパッケージ変数を初 期化し直してください。 ・ プリコンパイル時には、必ず release_cursor=yes オプションを指定してください。また、 thread=true オプションを指定しないでください。 ・ ローカルトランザクションを開始する場合、グローバルトランザクションを完了させておく必 要があります。また、グローバルトランザクションを開始する場合、ローカルトランザクション を完了させておく必要があります。

この例では、"ORCL"と いうデータベース名を使 用しています。デフォル トデータベースを使用す る場合は、データベース の宣言と AT 句の記述は 必要ありません。

(23)

Oracle OCI のプログラミング

OCI を使用して、Oracle データベースへのアクセスを行うためのプログラミング例について説明します。 なお、この例では、OCI のエラー処理を省略しています。詳細については、Oracle のリファレンスを参照して ください。

Oracle OCI での初期化処理

OCI インタフェースを初期化するために、プロセスで1度だけ、次の関数を呼び出します。 OCIInitialize( (ub4)OCI_DEFAULT, (dvoid *)0,

(dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0 );

Oracle OCI でのグローバルトランザクションの実行例

グローバルトランザクションを実行するためには、次のように記述します。

text *sqlstmt = (text *) "update a_account set BALANCE=:bal where ACCOUNTNO=:actno"; int actno, bal;

text *dbname = "ORCL"; OCIStmt *stmthp; OCIEnv *envhp; OCIError *errhp; OCISvcCtx *svchp; OCIStmt *stmthp; OCIBind *bnd1p = (OCIBind *) 0; OCIBind *bnd2p = (OCIBind *) 0; CosTransactions::Current_ptr current; try { //グローバルトランザクションを開始 current->begin();

} catch( CORBA::Exception& exc ){ return -1;

}

//環境ハンドルとサービスコンテキストの取得 envhp = xaoEnv( dbname );

svchp = xaoSvcCtx( dbname ); //エラーハンドルの初期化

(void) OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0); //ステートメントハンドルの初期化

OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) ); //SQL 命令の実行準備

OCIStmtPrepare( stmthp, errhp, selectp, (ub4)strlen((char *)selectp), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) ); //変数の割り当て

OCIBindByName( stmthp1, &bnd1p, errhp, (text *)":bal", -1, (dvoid *)&bal, (sword)sizeof(bal), SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4)0, OCI_DEFAULT );

OCIBindByName( stmthp1, &bnd2p, errhp, (text *)":actno", -1, (dvoid *)&actno, (sword)sizeof(actno), SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT ); // SQL 命令の実行

OCIStmtExecute( svchp, stmthp, errhp, (ub4)1, (ub4)0,

(CONST OCISnapshot *)NULL, (OCISnapshot *)NULL,

この例では、"ORCL"と いうデータベース名を使 用しています。デフォル トデータベースを使用す る場合は、データベース 名として空文字””を指定 してください。

(24)

OCI_DEFAULT ); try { //グローバルトランザクションをコミット current->commit(CORBA_TRUE); } catch( CORBA::Exception& exc ){ return -1; } ・ XA インタフェースでの接続を利用する場合、グローバルトランザクションとローカルトランザ クションのどちらの場合も、次の SQL 命令は使用できません。 トランザクションを完了させる OCITransCommit()と OCITransRollback() トランザクションを制御するための OCITransStart()、OCITransDetach()、 OCITransPrepare()と OCITransForget() データベースとの接続、切断を行う OCILogon()、OCILogoff()、OCISessionBegin()と OCISessionEnd() ・ カーソルは、トランザクションを完了させる前にクローズしてください。 ・ トランザクションブランチ間で、カーソルやグローバルパッケージ変数を共有することはでき ません。このため、1つのグローバルトランザクション内で、サーバアプリケーションのメソッ ドを複数回呼び出す場合には、メソッドが呼び出される度にカーソルやパッケージ変数を初 期化し直してください。 ・ サービスコンテキストは、XA インタフェースでデータベースとの接続を行った際に初期化さ れ、各スレッドに1つ割り当てられています。アプリケーションでは、必ず動作中のスレッド に割り当てられたサービスコンテキストを使用してください。マルチスレッド動作を行うサー バアプリケーションでは、メソッド呼び出しのたびに、サービスコンテキストを取得してくださ い。 ・ xaoEnv()と xaoSvcCtx()のパラメータで指定するデータベース名は、オープン文字列中の DB パラメータで指定する名前と一致させる必要があります。 ・ ローカルトランザクションを開始する場合、グローバルトランザクションを完了させておく必 要があります。また、グローバルトランザクションを開始する場合、ローカルトランザクション を完了させておく必要があります。

Microsoft SQL Server DB Library のプログラミング

DB Library を使用して、Microsoft SQL Server へのアクセスを行うためのプログラミング例について説明し ます。

なお、この例では、DB Library のエラー処理を省略しています。詳細については、Microsoft SQL Server の リファレンスを参照してください。

DB Library での初期化処理

DB Library を初期化し、ログイン情報を作成するために、プロセスで1度だけ、次の処理を実行します。 LOGINREC *login; dbinit(); login = dblogin();

DBSETLUSER( login, "SCOTT" ); DBSETLPWD( login, "TIGER" );

DB Library でのグローバルトランザクションの実行例

グローバルトランザクションを実行するためには、次のように記述します。

static char *sqlstmt = "update a_account set balance = %d where accountno = %d", bal, actno"; int err_handler( DBPROCESS*, int, int, int, char*, char* );

(25)

int actno, bal;

DBPROCESS *dbproc;

CosTransactions::Current_ptr current; //データベースとの接続

dbproc = dbopen( login, NULL ); //ハンドラの登録

dbprocmsghandle( dbproc, (DBMSGHANDLE_PROC)msg_handler ); dbprocerrhandle( dbproc, (DBERRHANDLE_PROC)err_handler ); //データベースの指定

dbuse( dbproc, "pubs" );

try { //グローバルトランザクションを開始 current->begin();

} catch( CORBA::Exception& exc ){ return -1;

}

//エンリストの実施

dbenlistxatrans ( dbproc, TRUE ); //SQL 命令のフォーマット

dbfcmd( dbproc, sqlstmt, bal, actno ); //SQL 命令の実行

dbsqlexec( dbproc ); dbresults( dbproc );

try { //グローバルトランザクションをコミット current->commit(CORBA_TRUE); } catch( CORBA::Exception& exc ){ return -1; } //コネクションの切断 dbclose(); ・ グローバルトランザクションを実行する場合、2 フェーズコミット用の次の関数は使用できま せん。 build_xact_string()、remove_xact()、scan_xact()、 start_xact()、stat_xact()、pen_commit()、 commit_xact()、close_commit() ・ カーソルは、トランザクションを完了させる前にクローズしてください。 ・ 複数のスレッド間でハンドルを共有する場合には、dbmsghandle()と dberrhandle()ではなく dbprocmsghandle()と dbprocerrhandle()を使って、ハンドル毎にメッセージハンドラを登録す る必要があります。

DB Library でのコネクションのプール管理

CORBA トランザクションサービスが提供するコネクション管理機能(RmSql インタフェース)を利用するため には、次のように記述します。

int err_handler( DBPROCESS*, int, int, int, char*, char* ); int msg_handler( DBPROCESS*, DBINT, int, int, char* ); LOGINREC *login; DBPROCESS *dbproc; long sessid = 0; // トランザクションに登録済みのハンドル有無を確認 if (::is_new_sqlsession(sessid) == false) { // プールからハンドルを取得

handle = ::get_sqlsession(sessid, WEBOTXS_SQL_SESSPOOL);

RmSql インタフェースの 詳細は、「API リファレン スマニュアル」の、「5. CORBA」の、「6. Transaction サービス」を 参照してください。

参照

関連したドキュメント

(a) 主催者は、以下を行う、または試みるすべての個人を失格とし、その参加を禁じる権利を留保しま す。(i)

タップします。 6通知設定が「ON」になっ ているのを確認して「た めしに実行する」ボタン をタップします。.

張力を適正にする アライメントを再調整する 正規のプーリに取り替える 正規のプーリに取り替える

貸借若しくは贈与に関する取引(第四項に規定するものを除く。)(以下「役務取引等」という。)が何らの

AC100Vの供給開始/供給停止を行います。 動作の緊急停止を行います。

 所得税法9条1項16号は「相続…により取 得するもの」については所得税を課さない旨

燃料デブリを周到な準備と 技術によって速やかに 取り出し、安定保管する 燃料デブリを 安全に取り出す 冷却取り出しまでの間の

By the method I, emotional recognition rate is 60% for close data, and 50% for open data(8 sentence speech of another speaker).The method II improves drastically the recognition