この特集のトップページへ
Chapter 6:ビジネスロジックの設計

  COLUMN    ルートオブジェクトから別のCOMオブジェクトを呼び出すときの不具合

 実は,Chapter4から説明してきたサンプルプログラムの一部が,COM+においては正しく動作しないことを確認した。その概要を説明しておく。

 動作しない部分とは,「トランザクションが有効な場面でルートオブジェクトから別のCOMオブジェクトを呼び出したとき,そのCOMオブジェクトがErr.Raiseメソッドを呼び出しても,エラーがルートオブジェクトに戻らない」というものである。実例を挙げると次のようになる。

 ここにfoo.rootというコンポーネントとbar.Childという2つのCOMコンポーネントがあるとする。foo.rootコンポーネントにはList 6-4に示すTestというメソッドが,bar.ChildコンポーネントにはList 6-5に示すTest2というメソッドが,それぞれ備わっているものとする。

List 6-4の9行目や10行目を見るとわかるように,bar.Childコンポーネントを実体化し,そのTest2メソッドを呼び出している。呼び出されたTest2メソッドでは,List 6-5の8行目にあるように,Err.Raiseメソッドを使って“エラーです”というエラーを発生させている。このエラーは,List 6-5の12行目以降でトラップされ,13行目にあるSetAbortメソッドの呼び出しによってトランザクションがアボートされ,14行目でエラーが再発行される。このエラーは,本来であれば呼び出し元のfoo.rootオブジェクトに伝わるはずである。つまり,foo.rootオブジェクトにおいても,“エラーです”というエラーが発生するはずだ。

 しかし実際には,foo.rootオブジェクトにおいては,“エラーです”というエラーが発生するのではなく,「'" メソッドは失敗しました '" オブジェクト」という意味不明のエラーメッセージが返される。つまり,bar.Childオブジェクト内で発生させたエラーメッセージは,その呼び出し元に伝わらないのである。

 List 6-4ならびにList 6-5のプログラムは,Windows NT 4.0 ServerのMTSにおいては正しく動作する。また,MicrosoftのNewsGroup(microsoft.public.platformsdk.complus_mts)には,COMクライアントとCOMサーバーがWindows 2000のときにだけ,この問題が発生するという投稿もある。

 この現象は,ジャストインタイムアクティベータが有効である(トランザクション動作しているある)COMコンポーネントにおいて発生する。「'" メソッドは失敗しました '" オブジェクト」というエラーは,一般に非アクティブ化されたCOMオブジェクトのプロパティを参照しようとしたときなどに発生する,MTSやCOM+のエラーである。いまのところ,これが仕様であるのかCOM+の不具合であるのかは不明であるため,本連載においては,これが「正しく動くようになるだろう」という仮定に基づいてサンプルプログラムを示す。この件については,詳細がわかり次第,追ってご報告する予定である。

 なお,この問題は,ルートオブジェクトから呼び出されるCOMオブジェクト(この例でいえばList 6-5bar.Childコンポーネントの13行目)において,SetAbortメソッドの代わりにDisableCommitメソッドを使うという方法で暫定的に対処できる。Windows 2000のCOM+機能を使ったアプリケーションの納品が迫っている,あるいは同じ症状で悩んでいるような場合には,この方法で適時対処していただきたい。

prevpg.gif Chapter 6 7/92 nextpg.gif