- PR -

EJBHome EJBLocalHomeへのconcurrentな呼び出しOK?

投稿者投稿内容
compass
会議室デビュー日: 2003/02/25
投稿数: 9
投稿日時: 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に
なっている可能性は高いので、最終的には自分でやるか見えない
ところでやっているかの違いにしかならないのかもしれませんが。
結局のところ時間優先か空間優先かみたいな問題に行き着くの
でしょうか?
typer
会議室デビュー日: 2003/06/04
投稿数: 5
投稿日時: 2003-06-05 12:37
EJBHomeとEJBLocalHomeについてはわかりませんが、InitialContextのインスタンスを
キャッシュしておいて使いまわすということに関しては、確かにマルチスレッド対応を
考慮する必要がありますが、「synchronizedを使用するなどの対応はかえって問題を
複雑化するだけである」という考え方もあるとのことです。
EJBHomeFactoryパターンに見られるInitialContextのインスタンスおよび、EJBHome、EJBLocalHomeのキャッシュ機構では、InitialContextのインスタンスの生成とEJBHome、
EJBLocalHomeのlookupは最初の1回にのみ行われる行為であるためというのが
理由なのかもしれません。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2003-06-05 14:34
ホームインタフェースのキャッシュは普通にやりますよ。

http://www-6.ibm.com/jp/developerworks/java/021122/j_j-ejb0924.html

が参考になると思います。
compass
会議室デビュー日: 2003/02/25
投稿数: 9
投稿日時: 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の想定するポータビリティは
失われる可能性がありますが。
compass
会議室デビュー日: 2003/02/25
投稿数: 9
投稿日時: 2003-06-05 15:22
ukさん
ご返答ありがとうございます。

まさに同じ記事の話になったのですが、
1つ前の投稿に書きましたが、あの記事では
EJBHomeへのconcurrent呼び出しは許されて
いることが前提と考えられますが、そもそも
それがよいのかどうか、ということが私の最初の
質問の意図です。

そして、あの記事では仕様でやってはいけないことが
明白なこと(InitialContextへのconcurrent呼び出し)を
見逃してしまっているようなところがあるので、
あの記事で前提としていると思われる、EJBHomeへの
concurrent呼び出しがOKであるということも、
信用できない気がする、というわけです。

InitialContextやEJBHomeへのconcurrent呼び出しが
OKであるならば、あの記事のような実装でなくても
気軽にいろいろな実装方法でキャッシュできると
思うのですが。

EJBの仕様に、EJBHomeへのconcurrent呼び出しに関する
記述が欠落している(と思います)、というのが
根本の問題ではありますが。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2003-06-05 17:39
compassさんの書き込み (2003-06-05 15:22) より:
>まさに同じ記事の話になったのですが、
1つ前の投稿に書きましたが、あの記事では
EJBHomeへのconcurrent呼び出しは許されて
いることが前提と考えられますが、そもそも
それがよいのかどうか、ということが私の最初の
質問の意図です。

確かにEJB仕様にもAPIリファレンスにもそれらしき記述は見当たりませんね。
仕様で保障していない以上は実装依存ということになるので、使用する製品のベンダに
確認するしかないですね。Weblogic、Websphere上では今まで問題が出たことはないです。

>そして、あの記事では仕様でやってはいけないことが
明白なこと(InitialContextへのconcurrent呼び出し)を
見逃してしまっているようなところがあるので、

「やってはいけない」んですか? 同期処理を保障していないだけでしょう。
そもそもこのContextオブジェクトへはlookupしかおこなわないので、同期処理はそもそも
考慮する必要はないだろう、というのが問題の記事の主張だと思います。
compass
会議室デビュー日: 2003/02/25
投稿数: 9
投稿日時: 2003-06-05 18:26
引用:

ukさんの書き込み (2003-06-05 17:39) より:
>そして、あの記事では仕様でやってはいけないことが
明白なこと(InitialContextへのconcurrent呼び出し)を
見逃してしまっているようなところがあるので、

「やってはいけない」んですか? 同期処理を保障していないだけでしょう。
そもそもこのContextオブジェクトへはlookupしかおこなわないので、同期処理はそもそも
考慮する必要はないだろう、というのが問題の記事の主張だと思います。




Contextへのconcurrentな呼び出しですが、
lookup()も含めてすべての呼び出しでだめなのだと
思っていました。APIドキュメントを見ても、
特にlookup()について、これだけは
concurrentに呼んでもよい、といった
記述はないと思います。
IBMの記事でも
「Contextオブジェクトへはlookupしかおこなわないので、
同期処理はそもそも考慮する必要はないだろう」
というように主張しているようには
読めなかったのですが、
記事のどのあたりからそのように
受け取られたのでしょうか?


「やってはいけない」という書き方は語弊が
あったかもしれません。
私の意図は、
「APIドキュメントで言っているのは、
Contextのインスタンスへの複数スレッドからの
呼び出し(lookupを含む)は、同期しなければ
いけないということは、同期せずに呼んだ場合
(要するにconcurrentに呼んだ場合)、
予期できない結果なることがある、と言う意味だと
思うので、私がアプリケーションプログラムを書く際に
Contextのインスタンスをconcurrentに
呼び出すコードを書いたとすると、その私の書いた
アプリケーションプログラムもやはり結果が
予期できないものになる」
といった程度のことです。このようになる場合は、
それはやってはいけないことなのだ、と個人的には
思っているので、上記のような書き方になって
しまったわけです。

uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2003-06-06 12:42
>IBMの記事でも
「Contextオブジェクトへはlookupしかおこなわないので、
同期処理はそもそも考慮する必要はないだろう」
というように主張しているようには
読めなかったのですが、
記事のどのあたりからそのように
受け取られたのでしょうか?

すいません、他の部分と混同していました。
この例では同期処理を行う、もしくはlookupごとにContextオブジェクトを生成しても
パフォーマンス上はそれほど影響がないだろうと思われるので、そうしておいたほうが
無難でしょうね。

スキルアップ/キャリアアップ(JOB@IT)