- - PR -
EJBHome EJBLocalHomeへのconcurrentな呼び出しOK?
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2003-06-05 11:23
件名に書いたとおりなのですが、
ServletやEJBを使って開発されている方でしたら きっとちょっとは考えたことがあることだと思うのですが、 JNDIのContextやEJBHomeやEJBLocalHomeを キャッシュして使ってよいものだろうかということに 関連したことです。 仕様によれば、JNDIのContextについてはconcurrentな 呼び出しはできないことになっているます。従って、 たとえばSingleThreanModelを実装していないServletでは、 生成したInitialContextのインスタンスをキャッシュしておいて、 その1つのインスタンスがconcurrentに呼ばれる可能性のあるような 使い方をすると動作が保障されなくなることが明らかです。 その場合はsynchronizedを使う必要があります。 (それならsynchronizedを使えばいいじゃん、という話もあります) それなら、Contextから取得した、たとえば、EJBHomeや EJBLocalHomeがキャッシュできればいいだろうと思うのですが、 EJBHomeとEJBLocalHomeについては、自分で仕様を見た限り concurrentに呼び出していいとも悪いとも記述が見つけられ ませんでした。EJBの仕様で"concurrent"で検索すると EJBのBeanへのconcurrent呼び出しについてはたくさん記述が あるのですが... いいとも悪いとも記述がないということは、いいと思って いいのか...(普通はそうは考えられないと思うのですが) そこで、EJBHomeとEJBLocalHomeへのconcurrentな呼び出しの 可否について何か情報をお持ちの方がいらっしゃいましたら、 ぜひ教えていただければと思っています。(実はちゃんと 仕様に書いてある、とか) 実際のところ、EJBHomeやEJBLocalHomeへconcurrentな 呼び出しができたとしても、内部のどこかでsynchronizedに なっている可能性は高いので、最終的には自分でやるか見えない ところでやっているかの違いにしかならないのかもしれませんが。 結局のところ時間優先か空間優先かみたいな問題に行き着くの でしょうか? | ||||
|
投稿日時: 2003-06-05 12:37
EJBHomeとEJBLocalHomeについてはわかりませんが、InitialContextのインスタンスを
キャッシュしておいて使いまわすということに関しては、確かにマルチスレッド対応を 考慮する必要がありますが、「synchronizedを使用するなどの対応はかえって問題を 複雑化するだけである」という考え方もあるとのことです。 EJBHomeFactoryパターンに見られるInitialContextのインスタンスおよび、EJBHome、EJBLocalHomeのキャッシュ機構では、InitialContextのインスタンスの生成とEJBHome、 EJBLocalHomeのlookupは最初の1回にのみ行われる行為であるためというのが 理由なのかもしれません。 | ||||
|
投稿日時: 2003-06-05 14:34
ホームインタフェースのキャッシュは普通にやりますよ。
http://www-6.ibm.com/jp/developerworks/java/021122/j_j-ejb0924.html が参考になると思います。 | ||||
|
投稿日時: 2003-06-05 15:01
typerさん
ご返答ありがとうございます。 不勉強なのですが、typerさんの文章の中の EJBHomeFactoryパターンというのは、 http://www-6.ibm.com/jp/developerworks/java/021122/j_j-ejb0924.pdf にあるものと同じもののことでしょうか? この記事に関して言えば、この記事が出たとき、まさにこれだ!、 と思ってすぐに読んでみたのですが(使い方次第といえば 言えなくもないですが)、この記事のEJBHomeFactoryの 実装方法については問題があるように思います。 そもそもEJBHomeFactoryのインスタンスをconcurrentに 呼び出しできません。 EJBHomeFactoryのインスタンスをconcurrentに呼び出すと、 InitialContextのインスタンスがconcurrentに呼び出される 可能性があります。 InitialContextのインスタンスへのconcurrentな 呼び出しはまずいので、これだけで問題ですが、 EJBHomeへのconcurrent呼び出しも発生する可能性があります。 EJBHomeFactoryを使用する側のコードには、常に1つ EJBHomeクラスの実装クラスのインスタンスが返されるからです。 この実装方法では、EJBHomeへの呼び出しはconcurrentが許される というのが前提になっていると考えざるを得ません。 このコードを信用するのであれば、EJBHomeへのconcurrentな 呼び出しは許されている、ということになりますが、 そもそもしてはいけないことが仕様で明らかになっている InitialContextへのconcurrentな呼び出しが起こるように なっているのを見てしまうと、信用してよいものか疑問になります。 EJBHomeFactory自体がSingletonパターンを使っているので、 この実装方法ではEJBHomeFactoryの1つのインスタンスが concurrentに呼び出されることが前提になっていると 推測するのが自然だと思います。EJBHomeFactoryのインスタンスへ の呼び出しと、返されるEJBHomeの実装クラスのインスタンスへの 呼び出しの両方を同期化するようにすればよいのですが、 この記事ではそのように使用されることを 想定しているのでしょうか? この記事を読んだ方で、この問題に関連する部分について この実装方法をそのまま採用した方がいらっしゃったら、 問題が起きたことがないか伺いたいところです。 あるいはこの実装方法は、たとえばIBMのWebSphereなど、 特定の実装製品では問題がないのかもしれません。たとえば、 WebSphereではEJBHomeの実装がconcurrent呼び出し できるようになっている、というようなことは 普通に考えられるからです。(しかし、InitialContextへの concurrent呼び出しの問題は依然として残ります) ただし、そうであってもJ2EEの想定するポータビリティは 失われる可能性がありますが。 | ||||
|
投稿日時: 2003-06-05 15:22
ukさん
ご返答ありがとうございます。 まさに同じ記事の話になったのですが、 1つ前の投稿に書きましたが、あの記事では EJBHomeへのconcurrent呼び出しは許されて いることが前提と考えられますが、そもそも それがよいのかどうか、ということが私の最初の 質問の意図です。 そして、あの記事では仕様でやってはいけないことが 明白なこと(InitialContextへのconcurrent呼び出し)を 見逃してしまっているようなところがあるので、 あの記事で前提としていると思われる、EJBHomeへの concurrent呼び出しがOKであるということも、 信用できない気がする、というわけです。 InitialContextやEJBHomeへのconcurrent呼び出しが OKであるならば、あの記事のような実装でなくても 気軽にいろいろな実装方法でキャッシュできると 思うのですが。 EJBの仕様に、EJBHomeへのconcurrent呼び出しに関する 記述が欠落している(と思います)、というのが 根本の問題ではありますが。 | ||||
|
投稿日時: 2003-06-05 17:39
compassさんの書き込み (2003-06-05 15:22) より:
>まさに同じ記事の話になったのですが、 1つ前の投稿に書きましたが、あの記事では EJBHomeへのconcurrent呼び出しは許されて いることが前提と考えられますが、そもそも それがよいのかどうか、ということが私の最初の 質問の意図です。 確かにEJB仕様にもAPIリファレンスにもそれらしき記述は見当たりませんね。 仕様で保障していない以上は実装依存ということになるので、使用する製品のベンダに 確認するしかないですね。Weblogic、Websphere上では今まで問題が出たことはないです。 >そして、あの記事では仕様でやってはいけないことが 明白なこと(InitialContextへのconcurrent呼び出し)を 見逃してしまっているようなところがあるので、 「やってはいけない」んですか? 同期処理を保障していないだけでしょう。 そもそもこのContextオブジェクトへはlookupしかおこなわないので、同期処理はそもそも 考慮する必要はないだろう、というのが問題の記事の主張だと思います。 | ||||
|
投稿日時: 2003-06-05 18:26
Contextへのconcurrentな呼び出しですが、 lookup()も含めてすべての呼び出しでだめなのだと 思っていました。APIドキュメントを見ても、 特にlookup()について、これだけは concurrentに呼んでもよい、といった 記述はないと思います。 IBMの記事でも 「Contextオブジェクトへはlookupしかおこなわないので、 同期処理はそもそも考慮する必要はないだろう」 というように主張しているようには 読めなかったのですが、 記事のどのあたりからそのように 受け取られたのでしょうか? 「やってはいけない」という書き方は語弊が あったかもしれません。 私の意図は、 「APIドキュメントで言っているのは、 Contextのインスタンスへの複数スレッドからの 呼び出し(lookupを含む)は、同期しなければ いけないということは、同期せずに呼んだ場合 (要するにconcurrentに呼んだ場合)、 予期できない結果なることがある、と言う意味だと 思うので、私がアプリケーションプログラムを書く際に Contextのインスタンスをconcurrentに 呼び出すコードを書いたとすると、その私の書いた アプリケーションプログラムもやはり結果が 予期できないものになる」 といった程度のことです。このようになる場合は、 それはやってはいけないことなのだ、と個人的には 思っているので、上記のような書き方になって しまったわけです。 | ||||
|
投稿日時: 2003-06-06 12:42
>IBMの記事でも
「Contextオブジェクトへはlookupしかおこなわないので、 同期処理はそもそも考慮する必要はないだろう」 というように主張しているようには 読めなかったのですが、 記事のどのあたりからそのように 受け取られたのでしょうか? すいません、他の部分と混同していました。 この例では同期処理を行う、もしくはlookupごとにContextオブジェクトを生成しても パフォーマンス上はそれほど影響がないだろうと思われるので、そうしておいたほうが 無難でしょうね。 | ||||
