- PR -

Stateless Session Bean のインスタンス変数の扱いについて

1
投稿者投稿内容
hanny
会議室デビュー日: 2003/07/31
投稿数: 13
投稿日時: 2006-10-26 10:20
EJB 1.1 の Stateless Session Bean を用いたシステムの保守を現在行っています。
(Solaris 9, Weblogic 8.1SP3)

Stateless Session Bean の挙動は
1. Homeインターフェース の create() メソッドをコール
2. インスタンスを取得(新規作成 または EJBコンテナのプールから)
3. ビジネスメソッドを実行
4. EJB Bean を EJBコンテナのプールに返す。
という動きをとると思います。

そのなかで色々な本や Webの資料を読んだのですが、以下 2つの疑問が解消しません。

A. インスタンスの利用のされ方は
a. 1つの EJBのインスタンスが同時に複数の EJBクライアントから利用される
b. 一度プールに返却された後に再利用される。

B. インスタンス取得時のインスタンス変数は
a. 初期値
b. 不定 (コンテナ依存)

A, Bについて色々なところで a, b両方の記述があり混乱しています。
ご存知の方がいらっしゃいましたらご教授ください。

また、併せてこれらについての Sun のドキュメントがありましたらその参照先を教えていただけると助かります。

以上、宜しくお願い致します。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-10-26 14:09
引用:

hannyさんの書き込み (2006-10-26 10:20) より:
A. インスタンスの利用のされ方は
a. 1つの EJBのインスタンスが同時に複数の EJBクライアントから利用される
b. 一度プールに返却された後に再利用される。



プールってひとつのインスタンスを同時に複数実行させないためじゃないですか?
複数実行を許可するのであれば、プールせずに1インスタンスだけ作って
処理させればいいので。

自分はそう思ってたんですけど・・・。

#そう言えば、Spring等はプールせずに複数実行する方針ですね。
#代わりにトランザクション関係にはThreadLocalが必要になると。

http://www.unix.org.ua/orelly/java-ent/ebeans/ch07_02.htm
>7.2.2.1. Transitioning to the Method-Ready Pool

ここを眺めると、開いたままのリソースはejbRemove()で閉じろと書いてあるので、
コネクション等をインスタンス変数に格納して再利用するのは可能なんでしょうね。

ライフサイクルはコンテナ次第ではとんでもなく長くなる可能性があるので、
下手に再利用しない方が無難だとは思います。

Stateless SessionBeanとは言っても、個々のインスタンスがStatelessではなく、
クライアントとの関係がStatelessなのだと考えればよいのではないでしょうか。

引用:

B. インスタンス取得時のインスタンス変数は
a. 初期値
b. 不定 (コンテナ依存)



インスタンス取得時って、EJB側ですか?参照側ですか?
EJB側は普通にコンストラクタを通った結果なのでは?

その後にsetSessionContext() ⇒ ejbCreate()が呼ばれて
初期化するタイミングが寿命の中で一度だけ与えられます。
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-10-26 16:32
引用:
EJB 1.1 の Stateless Session Bean を用いたシステムの保守を現在行っています。


EJBコンソーシアムをやっていた頃の懐かしい仕様書を引っ張り出してきました。

引用:
A. インスタンスの利用のされ方は
a. 1つの EJBのインスタンスが同時に複数の EJBクライアントから利用される
b. 一度プールに返却された後に再利用される。


Stateless Session Beanは、クライアントに依存する状態を保持していないことを、コンテナは利用してかまいません。したがって、aの実装も許されています(仕様書6.8)
ただし、同一インスタンスに対するメソッド呼び出しはコンテナがシリアライズするので、ビーン側はリエントラントを意識する必要はありません(仕様書6.5.2)

実はStateful Session Beanでもaの実装が許されていますが、その場合にはejbPassivateを呼んでインスタンス変数の値を退避するチャンスが与えられます。同じクライアントに割り当てられる時点にejbActivateで退避した値を復元することができます。
実際にはこんな面倒な実装を提供しているコンテナは無いのではないかと想像します。

引用:
B. インスタンス取得時のインスタンス変数は
a. 初期値
b. 不定 (コンテナ依存)


Stateless Session Beanはcreate時にejbCreateが呼ばれるわけではありません。プールに入るときにejbCreateが呼ばれます(仕様書6.9)
また上記のA-aの話もありますので、bということになります。

Stateful Session Beanはcreate時に必ずejbCreateが呼ばれますから、そこでインスタンス変数を初期化します。ここでもプーリングの話があるのでJava言語の初期値であることや、コンストラクタの設定値であることを前提にしてはいけません。原則的にすべてのインスタンス変数の値をejbCreateで初期化すべきです。

ちなみにEJBコンソーシアムのポータブルコンポーネント規約第2版を引用します:
引用:
規約2-1-2: ステートレスセッションBean は,ビジネスメソッドの実行開始時点でフィー
ルドが特定の値であることを前提としてはならない。
ステートレスセッションBean は、同一インスタンスを複数のクライアントに共有させ
ることでメモリの利用効率を確保する。したがって、ビジネスメソッドの実行開始時点で、Java 言語の初期値であることを前提としたり、直前に呼び出したビジネスメソッド実行終了時点の値であることを前提とすることができない。


hanny
会議室デビュー日: 2003/07/31
投稿数: 13
投稿日時: 2006-12-13 10:36
あしゅ様、よしだひろゆき様 返事が遅くなって大変申し訳ありませんでした。

EJB仕様については理解が不足していたところで、特にコンテナに「依存する」ことが明確になり大変助かりました。

ありがとうございました。
1

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