目次


LDD Today

Lotusエンタープライズ・インテグレーションのサーバーへの負荷を軽減するには

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: LDD Today

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:LDD Today

このシリーズの続きに乞うご期待。

リレーショナル・データベースにアクセスするプログラミング・インターフェースとして、Lotus Notesは複数のものを持っています。例えば、Lotus Connectors LotusScript Extensions (LC LSX)や、@DbColumn/@DbLookupといった式言語を使いODBCでアクセスする方法、LotusScript Data Object (LS:DO) でのODBC接続、JDBC接続などがあります。このように複数のアクセス方法があるものの、実際のアプリケーションでライブでのデータアクセス、すなわち操作時にリアルタイムでデータアクセスする場合には、管理上の大きな問題出てきます。それは、各ワークステーションがリレーショナル・データベースへ接続できるようにセットアップされている必要があることです。ここでは、リレーショナル・データベースでの作業をDominoへ移行した場合に発生する問題対処を、リアルタイムでデータアクセス時やバッジ処理でのデータアクセス時の両面において解説していきます。具体的に扱うテクニックの内容としては以下の通りです。

  • Lotus Enterprise Integrator(LEI)の複製あるいはカスタム・プログラムされた複製により、リファレンス情報をDominoデータベースにコピーしておき、更新を行う。
  • 定期実行エージェントを利用して、Enterprise Integrationタスクをバッジ処理で実行する。
  • DECSあるいはLEIのバーチャル・フィールド・アクティビティーを利用して、@Dblookupを普通に使う方法で、ライブで最新のデータを参照する。
  • サーバー上のエージェントを、Notesクライアントから起動して、データの取得や更新を行う。

どの技術を使うかは、アプリケーションの要求により異なります。分かりやすくするために、異なる方法で実装されたアプリケーション例を用意しました。この記事に関連するものとして、sample Lotus Notes database(US)がありますが、これにはここで紹介するコードが掲載されています。このアプリケーションは、Domino 6.0以降で動作するように設計されていますが、R5でもこのテクニックを適用することができます。この例では、@DBコマンドとLC LSXを利用しています。ただし、LC LSXのプログラミングに関する詳細はこの記事では取り扱いません。これについては、最近刊行されたRedbook、Implementing IBM Lotus Enterprise Integrator 6(US) をご覧ください。LC LSXに関するよい手引きとなるでしょう。また、バーチャル文書や、バーチャル・フィールドのキー文書を最新に保つやりかたなどの技術についてもカバーしています。

この記事では、読者の皆さんは経験を積んだNotesアプリケーション開発者であることを前提としています。

セットアップ

この記事におけるLC LSXコードはDominoサーバー上で動作することを前提としています。Domino Designerでスクリプトを編集する場合には、あるいはローカルで動作させる場合には、LC LSXがローカルのワークステーションにインストールされている必要があります。Nlsxlc.dllファイルがNotesプログラム・ディレクトリーにない場合には、Notesクライアントのインストーラーを実行し、修復モードでDomino Enterprise Connection Services (DECS)をインストールします。サンプル・アプリケーションの準備として、DECSあるいはLEIが実行されているDominoサーバーにアプリケーションを乗せ、制限なしのエージェントの実行権限を持つIDで設計要素に署名を行います。 このアプリケーションではリレーショナル・テーブルを利用しますが、これは自分自身で作成することもできます。まず最初に、DECSあるいはLEIの接続文書を作成して、例えばMicrosoft Accessといったテスト領域として使うリレーショナル・データベースへ接続できるようにします。そして、Create Sample Dataエージェントを実行します。そうすると、接続の選択を行い、そして新規テーブルの名称を入力するように画面が表示されます。このエージェントは、サーバーに対する負荷を軽減する例で、エージェントを実行するワークステーションからリレーショナル・データベースへ接続するかたちではないものです。

もともとのアプリケーション

カスタム・グラフィック・デザインを扱う企業の作業指示のアプリケーションをここでは扱います。注文を受けると、受注を受け付けた人はNotesクライアントを使って、フォームに注文の詳細を埋めていきます。その際にはNotesリッチテキストを使って、ざっくりとしたスケッチや提供されたものの内容も入れられます。

図1. 作業依頼のサンプル・アプリケーション
作業依頼のサンプル・アプリケーション
作業依頼のサンプル・アプリケーション

グレーの背景がついた顧客情報部分は、別のリレーショナル・データベースに格納されています。このアプリケーションでは、@DbColumn(ODBC)を使用して、アカウント番号のキーワード・リストを取得しています。ユーザーがアカウント番号を選択すると、フォームは@DbColumn(ODBC)を使って、フィールドの値を引き出します。例えば、キーワード参照の計算式はこのようになります。

リスト1. キーワード参照の計算式

@If(!@IsDocBeingEdited;
@Unavailable;
@Text(
@IfError(@DbColumn("ODBC":"NoCache"; "Offload Sample"; "userid"; 
" password " ; "Customers" ; "ID":"Discard"; "Ascending"); 
"No customer information available|") 
) )

そして、計算結果フィールドであるCustNameには下記のように設定します。

リスト2. CustName計算結果フィールドの計算式

@If(Customer = ""; 
"";
@IfError(
@DbLookup("ODBC":""; "Offload Sample"; "userid"; "password"; "Customers"; 
"CustomerName"; "ID"; @ToNumber(Customer));
"unknown"
) )

この例では、利用するユーザーはPCに、ODBCデータソースとしてOffload Sampleが定義されていなければなりません。管理コストや、各ユーザーがデータベースに接続するパフォーマンスコストを省くには、リレーショナル・データベースに関する作業を各ワークステーションで行わないようにしなければなりません。

レプリケーションを行い、参照データを複製する

LEIがインストールされているならば、複製アクティビティーを利用してリレーショナル・データベースからNotesへ参照情報をコピーすることができます。その上で、リレーショナル・データベースへ直接参照するのではなくて、Notesのデータベースを参照できるように参照式を書き換えておきます。タイムスタンプ複製を利用する場合には、NotesユーザーがNotesデータベースのレコードを編集することで、リレーショナル・データベースの情報を更新するようにできます。

LEIがインストールされていない場合には、LC LSXを使いLotusScriptで、独自のカスタム・レプリケーションをサーバー上定期実行するサーバー・エージェントを書くことができます。Replicate Customersエージェントは、LotusScriptでシンプルな「プライマリー・キー」の複製を実行するものです。これはLEIの複製機能の一部であり、これ以外にも様々なオプションがあります。また、さほど高速ではありませんが、基本的な作業はこなしてくれます。

どのようにデータを複製するかは別にして、複製されたデータがどのように使われているかを、サンプル・データベースにある以下の設計要素について見ていきます。

  • WorkOrder2フォームはオリジナルの作業依頼フォームと基本的に同じですが、参照機能を@DbColumnや@Dblookupで実現しています。オリジナルの作業依頼フォームではODBCで実装しています。
  • CustomerRecordフォームには、Customersのリレーショナル・テーブル列にマップされたフィールドがあります。Notes DBの各CustomerRecord文書は、それぞれCustomersテーブルの各行(レコード)に対応しています。
  • WorkOrder2フォームは(Customers)ビューを使用して、顧客リストのキーワードを読み取り、その顧客の詳細情報を参照するようになっています。
  • (CustReplicate)ビューはLEIの複製アクティビティーで自動的に作成されます。この中にはCustomerRecord文書がIDフィールドでソートされています。

全てのデータがNotesにあるため、WorkOrder2フォームは単純なNotesの設計になっています。例えば、キーワードの計算式は以下のようになっています。

リスト3. WorkOrder2フォームのキーワードの計算式

@If(!@IsDocBeingEdited; 
@Unavailable;
@Text(
@IfError( @DbColumn("":"NoCache"; ""; "(Customers)" ; 2) ; 
"No customer information available|")
) )

(Customers)ビューには以下の3つの列が設定されています。

  • 一列目はIDフィールドとしての顧客番号で、ソート目的のためにあります。
  • 二列目はキーワードの値を計算するものです。使いやすさの向上のために、顧客名を表示する同類のキーワードを定義しています。但し、数字だけが保管されています。
  • 三列目は複数値の形式で、他の全てのフィールドが入っています。そのため@DbLookupを一度実施するだけでデータを読み取れるようになっています。このような仕組みにすることで、オリジナルのフォームでは9度も繰り返して参照する必要だった手間が省けます。これと同じことは、計算結果の列を入れたリレーショナルなビューを使えば、オリジナルの例でも実現できます。パフォーマンスの面では良くなると思われますが、ユーザーのワークステーションを設定しなければならないという大きな問題を解決できません。

LEIレプリケーション機能を使いデータの複製を作成することで、モバイルユーザーはオフラインで作業が全て行えるようになります。複製されたローカル・レプリカには、作業を行う上で必要な情報は全て含まれていますので、レビューや新規作業依頼の作成をお客様先でも、ネットワークにつなげることなく行えます。また、ここでは行いませんが、双方向に複製するようにアプリケーションをセットアップしておけば、Notesの顧客データベースを更新すれば、リレーショナル・データベースにも反映されるようにできます。

良くない面としては、Notes文書のデータ、そして特に、ユーザーのローカル・レプリカは必ずしもリレーショナル・データベースと常に同期が取れているわけではないことです。リレーショナル・データベースのデータが頻繁に更新されるようなケースやデータの一貫性が求められる場合には、役にたたないことにもなります。 また、もちろんのこととして、Notesデータベースは複製された情報を保持しているため、ライブでリレーショナル・データベースで参照しに行くアプリケーションに比べて大きいファイルとなります。小さな顧客データベースの場合には問題となりませんが、数百万レコードといったデータがリレーショナル・データベースに格納されている場合には、Notesデータベースは巨大になり、動作が極めて遅くなる可能性がでてきます。

注意すべきことは、複製アクティビティーの設定には細心の注意を払い、2つのデータソースのレコード・リストが同じ順序で処理されるようにしなければなりません。もし、そうなっていない場合には、非常に多くのデータの追加と削除が発生しやすくなります。Notesでは、このようになるとパフォーマンスが悪くなり、電話回線でデータベースの複製を取るモバイル・ユーザーにとっては深刻になります。詳しくは、Technote (IBM/Lotusの技術情報文書) "LEI: Addressing Sort Order Issues when Replicating DB2/400 Data to a Notes database"(US)

DECS/LEIのバーチャル・フィールドを使ったライブ・アクセス

Notesデータベースに大量のデータを持たせないようにするには、(そしてまた、参照結果が最新の情報であるようにするには)、DECSあるいはLEIを使用して顧客の参照情報をバーチャル・フィールド化することです。こうすれば、Notesデータベースにはキーワード(この場合はID)だけを保存しておけば済みます。(その他のフィールドについては必要であれば任意で保存ができます。)文書内のフィールドを@DbLookupを使って読み出すと、サーバー上のバーチャル・フィールド・アクティビティーにより、リレーショナル・データベースへの参照がその場で行われ、ライブなデータが表示されます。バーチャル・フィールド・アクティビティーは以下のように設定されます。バージョン6.0より前では、バーチャル・フィールド・アクティビティーはRealTime Notesと呼ばれていました。

図2. バーチャル・フィールド・アクティビティー
バーチャル・フィールド・アクティビティー
バーチャル・フィールド・アクティビティー

VFCustomerRecordフォームは、この直前のセクションのCustomerRecordと同じものですが、異なる名前となっています。ユーザーが作業依頼のデータベースで顧客情報を編集することをさせることは意図していないので、Openイベントのモニターだけを行います。文書を複製することで、Notesのビューでフィールドの値を結びつけ、一度の参照で読み取ることができるようになります。バーチャル・フィールドなしには、このようにビューには表示することはできません。しかし、同じ結果を得る別の方法もあるのです。バーチャル・フィールドフォームのEvent Optionで、バーチャル・フィールドを読み取った後に実行するノーツ関数式を入れます。このケースでは、参照に使用するための計算結果フィールド値を数個追加しています。

図3. Post-Openの計算式
Post-Openの計算式
Post-Openの計算式

このイラストのように、以下の式をPost-Openイベントに入れてあります。

リスト4. Post-Openフィールドの計算式

FIELD Keywords := @Text(ID) + "." +@Trim(@ReplaceSubstring(CustomerName; "," ; " ")) + "|" + 
@Text(ID); FIELD LookupValue := CustomerName : BillingAddr1 : BillingAddr2 : BillingCity : 
BillingCountry : BillingState : BillingZip : MainPhone : Sector; 0

サーバー上にある文書をVFCustomerRecordフォームでアクセスする場合には、バーチャル・フィールド・アクティビティーがトリガーとなって、リレーショナル・テーブルからフィールドの値を読み取ります。(加えて、これらの値を使って、KeywordsフィールドやLookupValueを計算します。これらの値はNotesには格納されず、文書にアクセスが行われる度に、その場で「ライブ」で常に計算されることになります。それらの値は@Dbloookupを使って読み取ることが可能です。

Notesフィールドの値はビューには表示されません、つまり、@DbColumnを使っても値を読み取ることはできません。しかし、列の値の代わりにフィールド値を読み取るのであるならば、@DbLookupを使うことができます。サンプル・アプリケーションでは、(VFCustomersKeywords )でカテゴリー別のビューで、ビューに表示される文書のKeywordsフィールドを読み取り、キーワードのリストを取得しています。最初の列には、一定の値("All")は入っていて、ソートされています。これにより、キーワードから参照する以下の計算式を使って、各文書から同じフィールドの値を読み取れるようになっています。

リスト5. キーワード参照の計算式: 各文書から同一フィールドの値を読み取る

@If(!@IsDocBeingEdited; 
@Unavailable;
@IfError(
@DbLookup("":"NoCache"; ""; "(VFCustomersKeywords)"; "Al""; "Keywords"); 
"No customer information available|"
) )

この関数式はIDフィールドを参照せず、各アクティビティー文書のPost-OpenイベントでKeywordsフィールドを参照するように設定されています。ここではフィールド名を使用し、列番号は使用していません。これはビュー上にデータが表示されないためです。(@DbLookupは時折、列番号の代わりにフィールド名で参照した場合であっても、ビューの列からデータを読み取ることがあります。これが発生するのは、そのフィールド値のみを持つ列がひとつある場合です。バーチャル・フィールドの値はビューには表示されませんので、このような場合に該当する場合は避けなければなりません。

ユーザーが、顧客IDを選択すると、IDフィールドでソートされている(VFCustomersByID)ビュー@Dblookupで参照して、顧客情報が表示します。オリジナルのフォームでは、9つのバーチャル・フィールドをそれぞれ参照して値を取り出す必要がある場合には、パフォーマンスが低下する問題が発生します。そのため、LookupValueフィールドを用意して、Post-Openイベントで計算式を入れておき、9つのフィールドの取得を一度の参照で済ませて格納することで問題を回避しています。

参照文書の中に全てのフィールド値をそのまま保持する必要がないため、バーチャル・フィールドを利用することでより小さなNSFファイルで済むようになります。(但し、キー・データを保存した文書が膨大な場合にはパフォーマンス上の問題があります。)また、サーバー上のレプリカを利用すれば、必ず最新の情報を取得することができます。

モバイル・ユーザーがローカル・レプリカを作成した場合には、全ての参照文書を複製しますので、オフラインで利用することも可能です。が、必ずしもデータは最新というわけにはいきません。また、NSFにはキー・フィールドだけでなく、全てのフィールドデータを格納しているので、サーバー上のレプリカにくらべてサイズが極めて大きくなる可能性があります。そのため、必要な部分だけを選択レプリカでローカルに持ちたいと考えるようになるかもしれません。

Notesクライアントを使わず、別の方法でリレーショナル・データベースのデータが変更された場合には、Notes文書の更新日時データは変更されません。Notes文書が変更されない限り、バーチャル・フィールドの更新値を含んだローカル・レプリカの既存文書は、更新された文書を受け取ることはありません。Notes文書の更新日時が変更されれば複製されますので問題ありませんが、この問題を解決するには以下の方法があります。

  • LEIの複製を代わりに使用します。(この前のセクションを参照)
  • あるいは、リレーショナル・データベースの最終更新タイムスタンプがある場合には、LC LSXを使ってNotes文書側の最終更新日と比較します。リレーショナル・データベース側の更新日付が新しい場合には、Notes文書に変更を加えず保存します。そうすれば、次回の複製時に、その文書については必ず複製されます。
  • あるいは、別のサーバー上にNotesデータベースのレプリカがある場合には、二つのレプリカの値を比較するサーバー・エージェントを作成します。複製コピーと異なる文書がオリジナルのデータベースにある場合には、その文書を再度保存するようにします。

LEIバーチャル文書を使用したライブ・アクセス

LEI 6.0以降を利用している場合には、バーチャル文書アクティビティーを利用して、全てのデータが保存されたリレーショナル・データベースを参照するNotes文書を作成することもできます。これを行うには、リレーショナル・テーブルにNotesのヘッダー情報を保存するフィールドを追加する必要があります。あるいは、キー・フィールドを保存する参照テーブルを別に用意する必要があります。 Notesの設計はWorkOrder2フォームや(Customers)ビューと同じものです。LEI Administratorデータベースに保存されたバーチャル文書アクティビティー文書は、前に紹介したバーチャル・フィールド・アクティビティーと似ています。前の例と殆ど違いはありませんので、この方法を説明するための例として別のものは用意しません。 バーチャル文書を使用するメリットは以下の通りです。

  • サーバー上のレプリカを利用するユーザーは、最新の情報を入手できます。
  • バーチャル文書もローカル・レプリカに複製可能であるため、モバイル・ユーザーはオフラインで利用できます。また、既存の文書も複製され最新の情報が反映されます。
  • 新規にリレーショナル・レコードを作成し、Notes上に表示させるのに特別なアクションが必要ないこと。(バーチャル・フィールド機能を使った場合には、新規にキー文書を作成する必要があります。)
  • バーチャル文書のフィールドはビューでも利用可能です。そのため、Post-Openイベントで計算を行ってデータを入れるフィールドを用意しなくても済みます。
  • NSFファイルには情報は一切格納されませんので、Dominoサーバー上のスペースを広く用意しなくとも、巨大なデータを扱うことができます。(ビューのインデックスと全文索引のデータはサーバー上にあり、大きくなることがありますので注意が必要です。)

バーチャル文書を使用する場合に注意すべきことがあります。リレーショナル・データが外部のアプリケーションにより変更された場合には、タイムスタンプも更新する必要があります。そうしておかないと、Dominoサーバー側は文書が変更されたかどうかを判別できないからです。そうしておかないと、(Shift+F9で)ビューのインデックスを完全に再構築しない限り、ビューに変更内容が表示されないようになります。また、ローカル・レプリカの更新に失敗するようになります。

リモートからサーバー・エージェントをコールする

最後に紹介するテクニックは、NotesAgent.RunOnServerメソッドの活用で、Dominoサーバー・プラットフォームでEnterprise Integrationの作業を行わせ、クライアント上で動作しているLotusScriptプログラムに結果を返すものです。このテクニックは、DECSやLEIのアクティビティーや@Dblookupでは処理しきれないほど複雑な処理や巨大な処理行う場合に適しています。実際には、ここに紹介するシンプルなフォーム例で行わせるようなもの以上に手間がかかりますが、ここはテクニックのデモということで簡単なもので済ませています。

これをうまく動作させる鍵となるポイントは、サーバー・エージェントに情報をうまくわたせるかどうか、そして戻ってくる情報を受け取ることができるかどうかです。RunOnServerメソッドはパラメーター文書のnote IDを引数にとります。ワークステーション上で実行されるコードは、フィールド値をこの文書内に格納し、エージェントにどのようにすればよいかを伝えます。そうしてエージェントは同一文書に結果を書き込めるようになるわけです。

最大のパフォーマンスを出すアプリケーションにするためには、新規にパラメーター文書を毎回作成したり、削除するといったことが行われないようにしなければなりません。これは特にサーバー・プロセスが頻繁にコールされる場合に注意します。新規作成と削除の処理を行うと、削除スタブが残り、ビュー・インデックス作業や複製のパフォーマンスを低下させる原因となります。一方、パラメーター文書として1文書だけ使うことは行ってはなりません。サーバー・エージェントを利用する同時ユーザーが必ず一人であるという保証があれば別ですが、そうでない場合には同時に複数の人間が利用して、相互に干渉することになります。よい解決方法としては、サーバーで処理を行うユーザー毎に別々のパラメーター文書を用意することです。そして、エージェントの実行が終了しても削除しないようにしておきます。パスワードといった機密性の高い情報が含まれている場合には、不要になった時点でエージェントで削除することも考慮します。

パラメーター文書を作成したり、特定することは、完全に単純になるものではありません。しかし、サンプル・アプリケーションのスクリプト・ライブラリー、RunOnServerCallの中には再利用可能なGetParameterDocと呼ばれる関数が入っており、その作業をこなしてくれます。

注意事項ですが、パラメーター文書としてプロフィール文書を使うことはしないでください。プロフィール文書はメモリーにキャッシュされますので、他のプロセスによって内容が変更されたか否かをコードで検知することは困難です。必ず、Notes文書を使うようにしてください。

Notes文書はコードで記述さえすればどのような名前のフィールドでも格納が可能なので、エージェントの結果をユーザーに表示する必要がなければ、パラメーター文書についていちいちフォームを用意する必要がありません。単にフィールド名を用意して、コード内で使用するだけで済みます。

WorkOrder4フォームには、コードの最終部分のコールが含まれています。ここでは、RemoteLookupエージェントをサーバー上でコールしています。ここでは、以下の4つのフィールド名をパラメーター文書に入れてあり、データをエージェントに送信します。

  • Connection (string)は、どのデータが読み込まれるかを指定するDECS/LEIの接続の名称です。
  • Condition (string)はSQL文で、選択するレコードを指定します。
  • Fieldnames (string)は読み取られるフィールドの一覧で、コンマで区切られています。空欄にした場合には、全てのフィールドを選択したことを意味します。
  • Ordernames (string)は、Selectステートメント文命令によるSQL文です。
  • Limit (number)は、読み取る最大レコード数です。

エージェントがエラーになった場合には、パラメーター文書のStatusテキスト・フィールドにエラー・メッセージを保管します。そうしておかないと、StatusフィールドがNullのままになり、リレーショナル・テーブルから読み取った各フィールドに対応して、テーブル列と同じ名称を持ったフィールドがNotesに作成されます。複数のレコードが読み込まれた場合には、Notesのフィールドに複数値で格納されます。繰り返しになりますが、これらの選択は任意で行われる物で、アプリケーションのニーズで決定されるものです。コールの最後に、キーワード値のリストを読み取るコードを示します。

リスト6. キーワード値のリストを読み取るコード

Use "RunOnServerCall"
Function LoadKeywords(uidoc As NotesUIDocument) As Boolean
‘returns True if the keyword load succeeded, else shows error
‘message and returns False. 
On Error Goto errortrap
Dim session As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent 
Dim docParm As NotesDocument

Set db = session.CurrentDatabase 
Set agent = db.GetAgent("RemoteLookup")
Set docParm = GetParameterDoc(session, db)
docParm.Connection = "Offload Customers"
docParm.Limit = 1000
docParm.Condition = "" 
docParm.Fieldnames = "ID,CustomerName"
docParm.Ordernames = "ID" 
docParm.Save True, False, True
If agent.RunOnServer(docParm.NoteID) < > Then
Msgbox "Cannot run agent!" 
Else
Set docParm = GetParameterDoc(session, db) ' reload
If docParm.Status(0) < > "" Then
Msgbox "Server agent error: " & docParm.Status(0)
Else
uidoc.Document.KeywordChoices = Evaluate( _
{ @Text(ID) + ": " + CustomerName + "|" + @Text(ID) }, docParm)
End If
End If
LoadKeywords = True
Exit Function

ErrorTrap:
Msgbox Err, Error & " // LoadKeywords:" & Erl
Exit Function
End Function

GetParameterDoc関数は、エージェントに対して情報を渡す文書を指定、あるいは新規に作成を行います。どの情報を必要としているかをエージェントに伝えるフィールドを設定しておき、文書を保存することで、エージェントが変更されたことをわかるようにしています。エージェントが正しい動作を行い結果を返すと、 文書からフィールドの値を読み取り、IDとCustomerNameにセットします。こうすることで、現在の文書のフィールドを更新することができます。パラメーター文書から値を取り出すエージェント・コードを以下に示します。 Here’s the agent code to retrieve the parameter document:

リスト7. パラメーター文書から値を取り出すエージェント・コード

Sub Initialize
Dim lcses As New LCSession 
lcses.ConnectionPooling = True
Dim session As New NotesSession 
Dim db As NotesDatabase
Dim agent As NotesAgent
Dim strNoteID As String
Dim docParm As NotesDocument 

' get information about the environment.
Set db = session.CurrentDatabase 
Set agent = session.CurrentAgent
strNoteID = agent.ParameterDocID 

' locate the document that has the parameters we need to do our stuff. 
On Error Goto ErrorTrap 
Set docParm = db.GetDocumentByID(strNoteID)
If docParm Is Nothing Then 
Print "A valid parameter document was not supplied."
Exit Sub
End If

こうして、エージェントはdocParmフィールドの値を読み取りConnectionやConditionやその他呼び出し側から指定された値を取得します。この記事で扱う内容を超えて、どのようにデータベースへのアクセス・タスクが動作しているかについて、エージェントのコードを見ていくと役に立つことであると思われるでしょう。

また、現在の文書をパラメーター文書として利用することができます。(エージェントが必要とするフィールドが文書内にあり保存されていることが条件です。)しかし、NotesSession.DocumentContextプロパティーとNotesDatabase.UnprocessedDocumentsプロパティーは、現在の文書では扱えません。サーバーはどの文書がワークステーション上で開いているのか、ParameterDocIDを使って教える以外に、知るすべがありません。

RunOnServerは、サーバー上のレプリカのエージェントを利用する必要があります。サーバーへの接続ができる状態で、ローカル・レプリカを使用する場合には、サーバー上のレプリカを必ず探し出して、サーバー上のレプリカにあるパラメーター文書とエージェントが使えるようになっていなければなりません。例えばあるリレーショナル・データベースへ接続できるサーバーが限定されている場合など、プロセスの中にはある特定のDominoサーバーで処理しなければならない場合があります。RunOnServerCallスクリプト・ライブラリーにGetServerDBという関数が入っていますが、これは現在使用しているデータベースについて、指定したサーバー上のレプリカを探すものです。ローカル・レプリカや別のサーバー上のレプリカで作業をしている場合に便利です。Notesクライアント上で動作させるには、以下のコードを使います。

リスト8. クライアント側のコード

Dim dbCurrent As NotesDatabase 
Dim dbServer As NotesDatabase 
Dim agent As NotesAgent 
Set dbCurrent = session.CurrentDatabase
Set dbServer = GetServerDB(dbCurrent, " servername", False)
Set agent = dbServer.GetAgent("agentname")

このように、dbの代わりにdbServerを使います。3つ目の引数であるGetServerDBは、ある特定のサーバーで動作させる場合に使うものです。Falseの場合は、どのサーバーでも構わないことを意味します。もちろん、特定のサーバーで動作させる必要がある場合には、データベースのパスをハードコードすることもできますが、サーバー管理者がデータベースを移動させた場合にはエラーとなってしまいます。

ローカル・レプリカをオフラインで利用する必要性がなければ、RunOnServerを使うのもひとつの解決策になります。コードが多少、長いですが、複雑なタスクを起動してすぐに結果を見たい場合に適しています。例えば、その都度その都度必要な時に、リレーショナル・データベースからデータを引き出して統計情報を作成して表示させたい場合の実装方法としてよいでしょう。エージェントを使って、パラメーター文書のリッチテキスト・フィールドにレポートを作成することもできます。

他のオプション

Domino HTTPを起動している場合には、LotusScriptでDominoエージェントを作成して、URL文字列あるいはHTTP PUTの処理でデータを読み出して、パラメーターを受けることができます。Printステートメントをエージェントで使用して呼び出し側にデータを戻すようにすることができます。 また、Domino Webサービスを使用することもできます。WebサービスとコンシューマーをLotusScriptで組むことができますが、その説明と例はDomino Designerヘルプに収められています。

結論

以上のテクニックを理解したことで、レパートリーの幅がひろがったことと思います。データベースに関わる負荷を下げるに、どのようなオプションがあるかを思い出してください。まず、アプリケーションのニーズを吟味することが必要です。その上で、どの方法が最適であるかを決定します。

  • アプリケーションは、リレーショナル・データベースに即時アクセスして読み書きする必要があるのか?それとも、エージェントを使って、またはLEIの複製アクティビティーを使ったバッチモードの処理で十分か。
  • アクセスする情報は、どれくらいの「鮮度/即時性」が必要か。また、どのくらいの頻度で変更が加えられるのか?
  • モバイル・ユーザーのサポートが必ず必要なアプリケーションか?
  • ローカル・レプリカを使用する、オンラインユーザーをサポートする必要があるのか?
  • リレーショナル・データベースのテーブルの追加や変更が許可されているか?(バーチャル文書を作成する上で必要になります。)
  • データセットがどのくらいのサイズか?
  • サーバーは今まで以上に負荷をかけても耐えられるか?

以上の質問への回答によって、この記事でお話ししてきました様々なアプローチの中で、どれが一番適しているかが決まってくると思います。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Lotus
ArticleID=337362
ArticleTitle=LDD Today: Lotusエンタープライズ・インテグレーションのサーバーへの負荷を軽減するには
publish-date=01052004