目次 | |

6. セションBean部品契約

6.では,セションBeanとそのコンテナとの間の契約を規定し,セションBeanインスタンスのライフサイクルを定義する。

セションBean状態管理の開発者のビュー及びそれを管理するコンテナの責任を定義する。

6.1 概観

定義によって,セションBeanインスタンスとは,それを生成するクライアントの外延とする。 セションBeanインスタンスの一生は,コンテナ固有のタイムアウト又は実行サーバのクラッシュによっても終了するかもしれない。 このため,使用中のインスタンスがなくなった場合に備え,クライアントは, 常に新しいインスタンスを再生成可能にしておかなければならない。

セションBeanの会話状態は,通常データベースに書き込まれない。Bean開発者は,単に,Beanのフィールドにそれを記憶し,Beanの寿命中は値が保持されるものと仮定する。

一方,キャッシュされたデータベースデータは,Beanで明示的に管理しなければならない。 Beanは,Beanのトランザクション完了に先立って,キャッシュされたデータベース更新をすべて書き込まなければならないし, 次のトランザクション開始時には,失効した可能性のあるデータベースデータのすべてのコピーを一新しなければならない。

6.2 目標

セションBeanモデルは,同じ機能をクライアントで直接開発するのと同程度の単純性をもつセションBeanの開発を目的とする。

セションBeanコンテナは,セションBeanのライフサイクルを管理し,Beanの動作が必要となる場合にはそれを通知し, Bean実装が大量のクライアントでもサポート可能とするために完全なサービスを提供する。

6.の残りでは,セションBeanのライフサイクルを詳しく示し,さらに,Beanとそのコンテナとの間のプロトコルについて示す。

6.3 コンテナの作業集合の管理

作業集合のサイズを効率的に管理するために,セションBeanコンテナは,使用していないセションBeanの状態を, 一時的に2次記憶装置に転送する必要があるかもしれない。作業集合から2次記憶装置への転送を,非活性化と呼ぶ。 2次記憶装置から作業集合への転送を,活性化と呼ぶ。

Beanがトランザクション状態にない場合だけ,コンテナは,セションBeanを非活性化してよい。

コンテナの状態管理を支援するために,セションBeanは,配置時に,次の状態管理モードのいずれかを指定する。

6.4 会話状態

状態付きセションBeanの会話状態は,そのフィールド値に, セションBeanのフィールドから到達可能なオブジェクトの推移閉包を加えたものとして定義する。

セションBeanインスタンスの推移閉包は,Javaプログラム言語に対応する標準直列化プロトコルで定義する。 エンタプライズBeanインスタンスを直列化することによって記憶されるフィールドは,エンタプライズBean状態の一部と考えられる。

拡張規定の場合には,セションBeanの会話状態は,オープンされた資源を含んでもよい。例としては,オープンしたファイル, オープンしたソケット及びオープンしたデータベースカーソルがある。セションBeanが非活性化されている間は, コンテナは,オープンされた資源を保持することはできない。このセションBeanの開発者は,通知ejbPassivate及び通知 ejbActivateを使用して,資源を閉じたり,開いたりしなければならない。

6.4.1 インスタンス非活性化及び会話状態

コンテナは,インスタンス上のメソッドejbPassivateを呼び出した後で,そのインスタンスの状態に関する Javaプログラム言語の直列化(又はそれと同等なもの)を実行する。エンタプライズBean開発者は,インスタンスの状態を ejbPassivate完了後に直列化可能としなければならない。インスタンスがejbPassivate後に直列化できない場合は, コンテナが,インスタンスを破壊する可能性がある。

インスタンスは,他のEJBオブジェクト(セションオブジェクト又は実体オブジェクト)へのEJBオブジェクト参照を保持しているかもしれない。 コンテナがejbPassivate後にインスタンスを非活性化する場合,非活性化されたインスタンスと共に, そのEJBオブジェクト参照を記憶しなければならない。ejbActivate前にインスタンスの状態をロードする場合には, これらのオブジェクト参照を再構築しなければならない。

セションコンテナは,非活性化されたセションインスタンスの状態を記憶するのに, Javaプログラム言語の直列化プロトコルを使用する必要はないが,結果は等価にならなければならない。 ただし,活性化の間,コンテナがtransientフィールドの値をリセットする必要はない(注を参照。)。 エンタプライズBeanのフィールドを“transient”と宣言することは,一般的には,望ましくない。

このことは,コンテナが,インスタンス上でJavaプログラム言語に対応する実際の直列化プロトコルを実行せずに, 特殊化したJVMを使用して,インスタンスの状態をスワップアウト可能とすることに注意すること。

6.4.2 会話状態でのトランザクションロールバックの効果

セションBeanの会話状態は,トランザクション的ではない。Beanのトランザクションがロールバックしても, セションBeanの会話状態は,自動的には初期状態にロールバックされない。

ロールバックによってセションBeanの会話状態が使用データベースの状態と矛盾する結果になる場合,Bean開発者は, 手動でその状態をリセットするために通知afterCompletionを使用しなければならない。

6.5 セションBeanとコンテナとの間のプロトコル

コンテナ自体は,セションBeansに実際のサービスを要求しない。コンテナが行うBean上の呼出しが, Beanにコンテナサービスへのアクセスを提供し,コンテナが発行する通知を配布する。

6.5.1 必須インタフェースSessionBean

すべてのセションBeansは,インタフェースSessionBeanを実装しなければならない。

メソッドsetSessionContext()は,Beanのコンテナによって呼び出され,セションBeanインスタンスとコンテナが維持する文脈とを 関連付ける。通常,セションBeanは,セション文脈を会話状態の一部として保持する。

通知ejbRemoveは,インスタンスがコンテナによって除去される過程にあることを知らせる。 ほとんどのセションBeansは,清算するデータベース又は資源状態をもたないので,通常は,このメソッドは実装されない。

通知ejbPassivateは,コンテナの意図がインスタンスの非活性化にあることを知らせる。通知ejbActivateは, ちょうど今,再活性化されたことをインスタンスに知らせる。コンテナは,非活性化の間, セションBeanインスタンスの会話状態を自動的に維持するため,ほとんどのセションBeansは,これらの通知を無視することができる。 これらは,インスタンスの非活性化に先立って閉じられ,インスタンスの活性化の間に再び開かれる必要があるオープンされた資源を, 拡張Beansが維持できることを目的とする。

6.5.2 インタフェースSessionContext

すべてのBeanコンテナは,SessionContextをBeanインスタンスに提供する。これによって,Beanインスタンスは, コンテナが維持するインスタンス文脈にアクセスできる。インタフェースSessionContextは,次のメソッドをもつ。 コンテナは,インタフェースUserTransactionを,トランザクション属性TX_BEAN_MANAGED をもって配置されたBeanでだけ利用可能とし、異なるトランザクション属性の値をもって配置されたBeanによって呼び出された場合には, インタフェースgetUserTransactionは失敗することに注意すること。

6.5.3 選択的インタフェースSessionSynchronization

セションBeanは,インタフェースjavax.ejb.SessionSynchronizationを,選択的に実装できる。 このインタフェースは,Beanにトランザクション同期通知を提供する。セションBeansは,これらの通知を使用して, トランザクション内にキャッシュされたデータベースデータを管理する。

通知afterBeginは,新しいトランザクションが開始したことをセションインスタンスに知らせる。 この時点で,インスタンスは,すでにトランザクション内に存在し, トランザクションの適用範囲内で要求されたデータベース作業をすべて実行してよい。

通知beforeCompletionは,セションインスタンスのクライアントが現トランザクション上での作業を完了した場合で, インスタンスの資源をコミットする前に,発行される。この時,キャッシュされたデータベース更新を,すべて書き出すことが望ましい。 インスタンスは,セション文脈上でメソッドsetRollbackOnly()を呼び出すことによって, トランザクションをロールバックすることができる。

通知afterCompletionは,現トランザクションが完了したことを知らせる。trueの完了状態は, トランザクションがコミットしたことを示す。false状態は,ロールバックが発生したことを示す。 セションインスタンスの会話状態はトランザクション的ではないので,ロールバックが発生した場合, 手動でその状態をリセットする必要があるかもしれない。

6.5.4 業務メソッド委託

エンタプライズBeanの遠隔インタフェースは,クライアントが呼び出せる業務メソッドを定義する。 エンタプライズBeanの遠隔インタフェースは,コンテナツールが生成するEJBオブジェクトクラスによって実装される。 EJBオブジェクトクラスは,業務メソッドの呼出しを,エンタプライズBeanクラスにおいて一致する業務メソッドの実装に委託する。

6.5.5 セションBeanのメソッドejbCreate()

クライアントは,Beanのホームインタフェースで定義されるメソッドcreate()を使用して,セションBeanインスタンスを生成する。 Beanのホームインタフェースは,Bean開発者が提供する。つまり,その実装は,Beanのコンテナが生成する。

コンテナは,セションBeanのインスタンスを3段階で生成する。第1段階では,コンテナがBeanクラスのメソッドnewInstance() を呼び出して,Beanインスタンスを生成する。第2段階では,コンテナがメソッドsetSessionContext()を呼び出して, 文脈オブジェクトをインスタンスに渡す。第3段階では,クライアントの呼び出すメソッドcreate()のシグネチャと シグネチャが一致するインスタンスメソッドejbCreate()を,コンテナが呼び出す。クライアントから送信される入力パラメタは, メソッドejbCreate()に渡される。

各セションBeanは,少なくとも一つのメソッドejbCreate()をもたなければならない。セションBeanのメソッドcreate() の個数及びシグネチャは,各EJBクラスに固有とする。

セションBeanは,Beanとそのクライアントとの間で,固有の私的な会話を表現するので,その生成パラメタは,クライアントが その使用に合わせてBeanインスタンスを個別化するための情報を含む。

6.5.6 セションBeanメソッドの直列化

コンテナは,各インスタンスへの呼出しを直列化する。ほとんどのコンテナが,Beanの多くのインスタンスの並行実行をサポートする。 しかし,各インスタンスには,メソッド呼出しの直列化された列だけが見える。そのため,セションBeanを再入可能にコード化しなくてよい。

コンテナが直列化するメソッド呼出しには,コンテナ自体が行うサービスコールバックだけでなく, インスタンスのEJBオブジェクトを通じて配布されるメソッド呼出しを含む。例えば,コンテナは, インスタンスが業務メソッドを実行する間,インスタンス上でメソッドejbPassivate()を呼び出してはならない。

この規則は,セションBeanインスタンスへの“ループバック”呼出しが文法に合わないことを意味する。 ループバック呼出しの例としては,クライアントがインスタンスAを呼び出す場合に,インスタンスAがインスタンスBを呼び出し, BがAを呼び出す場合がある。BからAへのループバック呼出しを試みると,その結果として,コンテナは,Bに java.rmi.RemoteExceptionを投げる。

6.5.7 セションBeanメソッドのトランザクション文脈

セションBeanのメソッドafterBegin()及びメソッドbeforeCompletion()は,Beanがトランザクション的な場合, 常に適正なトランザクション文脈で呼び出される。

セションBeanのメソッドnewInstance(),メソッドsetSessionContext(),メソッドejbCreate(), メソッドejbRemote(),メソッドejbPassivate(),メソッドfinalize(),メソッドejbActivate(), メソッドafterCompletion()などは,常にトランザクションなしで呼び出される。そのため,例えば,セションBeanのメソッド ejbCreate()又はメソッドejbRemove()でデータベースを更新するのは,通常,誤りとなる。

セションBeanの配置記述子は,業務メソッドがトランザクション付きで呼び出されるかどうかを決定する。

6.6 状態付きセションBeanの状態図

図6.1は,状態付きセションBeanインスタンスのライフサイクルを示す。
 
6.6
図6.1 状態付きセションBeanインスタンスのライフサイクル

状態付き及びトランザクション的なセションBeanインスタンスのライフサイクルは,次のとおりとする。

6.6.1 トランザクションに対する制限

状態図は,クライアントが呼び出した業務メソッドのトランザクション範囲に,次の制限を課す。制限はコンテナによって実施され, クライアントプログラマに見えなければならない。

6.7 状態付きセションBeanの系列図

6.7では,クラス間の相互作用を例示する系列図を示す。

6.7.1 注意事項

系列図には,“コンテナ提供クラス”というラベルの付いた箱がある。これは,コンテナの一部であるクラスか, 又はコンテナツールが生成したクラスかのいずれかとする。このクラスは,コンテナの実装に固有なプロトコルによって, 互いに通信する。そのために,このクラス間の通信は,図には示さない。

図示したクラスは,規定的な実装ではなく,説明的な実装と考えるほうがよい。

6.7.2 セションオブジェクトの生成

図6.2は,トランザクション的なセションエンタプライズBeanの生成を示す。
 
6.2
図6.2 セションオブジェクトの生成

6.7.3 トランザクションの開始

図6.3は,トランザクション開始時に実行されるプロトコルを示す。
 
6.3
図6.3 トランザクションの開始

6.7.4 トランザクションのコミット

図6.4は,セションエンタプライズBeanインスタンスに対応するトランザクションの同期プロトコルを示す。
 
6.4
図6.4 トランザクションのコミット

6.7.5 トランザクション間のインスタンスの非活性化及び活性化

図6.5は,セションエンタプライズBeanインスタンスの非活性化及び再活性化を示す。 非活性化は,コンテナの要求に基づいて,自発的に発生する。活性化は,クライアントがメソッドを呼び出す場合に発生する。
 
6.5
図6.5 トランザクション間のインスタンスの非活性化及び活性化

6.7.6 セションオブジェクトの除去

図6.6は,セションBeanの破壊を示す。
 
6.6
図6.6 セションオブジェクトの破壊

6.8 無状態セションBeans

無状態セションBeansは,会話状態をもたないセションBeansとする。つまり,クライアントが呼び出すメソッドの提供に関与しない場合には, 各Beanインスタンスは同一となることを意味する。

無状態セションBeanのホームインタフェースは,セションBeanの遠隔インタフェースを返す引数のないメソッドcreate() をもたなければならない。ホームインタフェースは,それ以外のメソッドcreate()をもってはならない。 セションエンタプライズBeanクラスは,単一のメソッドejbCreate()を定義しなければならない。 このメソッドejbCreate()は引数をもってはならない。

無状態セションBeanのインスタンスは,すべて等しいので,コンテナは,利用可能なインスタンスのいずれに対しても, クライアントの作業を委託することを選択できる。

コンテナは,現在のクライアント負荷に必要とされる個数のインスタンスを保持するだけでよい。クライアントの“思考時間”のために, 通常は,この数は稼働中のクライアント数よりかなり少ない。非活性化は,無状態セションには必要ない。 クライアントの作業負荷が増大し,無状態セションBeanインスタンスが必要な場合は,コンテナがそれを生成する。 無状態セションBeanが,現クライアント作業負荷を処理する必要がない場合には,コンテナは,その無状態セションBeanを破壊できる。

無状態セションBeansは,コンテナの実装に依存して,多数のクライアントの支援に必要な資源を最小化するので, この手法を使用するアプリケーションは,状態付きセションBeansを使用するアプリケーションよりは拡張性に富む。 この利点は,無状態Beansを使用するクライアントアプリケーションではその複雑度が増すので,相殺されるかもしれない。

クライアントは,無状態セションBeanのホームインタフェース上で,状態付きセションBeanと同様に,メソッドcreate() 及びメソッドremove()を使用する。クライアントは,自分がEJBインスタンスのライフサイクルを制御していると考えるが, コンテナが,create()呼出し及びremove()呼出しを処理している。この場合,必ずしもEJBインスタンスを生成 及び除去する必要はない。

クライアントと無状態インスタンスとの間には,固定した対応づけは存在しない。コンテナは,クライアントの作業を,単に, メソッドの準備が完了している利用可能な任意のインスタンスに委託する。

無状態セションは,インタフェースjavax.ejb.SessionSynchronizationを実装してはならない。

6.8.1 無状態セションBeanの状態図

クライアントが無状態セションBean参照の上でメソッドを呼び出す場合,コンテナは, メソッドの準備が完了しているインスタンスのうちの一つを選び出し,メソッド呼出しを委託する。

図6.7は,無状態セションBeanインスタンスのライフサイクルを示す。
 

6.7
図6.7 無状態セションBeanインスタンスのライフサイクル

セションBeanインスタンスのライフサイクルは,次のとおりとする。

6.9 無状態セションBeanの系列図

6.9では,系列図によって,クラスの相互作用を図示する。

6.9.1 クライアント呼出しcreate()

図6.8は,無状態セションBeanが実装するEJBオブジェクトの生成を示す。
 
図6.8 EJBオブジェクトの生成

6.9.2 業務メソッド呼出し

図6.9は,業務メソッドの呼出しを示す。
 
図6.9 業務メソッドの呼出し

6.9.3 クライアント呼出しremove()

図6.10は,無状態セションBeanが実装するEJBオブジェクトの破壊を示す。
 
6.10
図6.10 EJBオブジェクトの破壊

6.9.4 プールへのインスタンス付加

図6.11は,メソッド準備完了プールに,インスタンスを付加するコンテナの系列を示す。
 
6.11
図6.11 メソッド準備完了プールへのインスタンスの追加

図6.12は,メソッド準備完了プールからインスタンスを除去するコンテナの系列を示す。
 

6.12
図6.12 メソッド準備完了プールからのインスタンスの除去

6.10 エンタプライズBean提供者の責任

6.10では,エンタプライズBeanをすべてのEJBコンテナに確実に配置できるための, セションエンタプライズBean提供者の責任を示す。

6.10.1 クラス及びインタフェース

エンタプライズBean提供者は,次のクラスファイルを提供する責任をもつ。

6.10.2 エンタプライズBeanクラス

セションエンタプライズBeanクラスの要件は,次のとおりとする。

6.10.3 メソッドejbCreate()

エンタプライズBeanクラスは,一つ以上のメソッドejbCreate()を定義しなければならない。 この場合,メソッドejbCreate()のシグネチャは,次の規則に従わなければならない。

6.10.4 業務メソッド

クラスは,ゼロ以上の業務メソッドを定義してよい。その場合,業務メソッドのシグネチャは次の規則に従わなければならない。

6.10.5 エンタプライズBeanの遠隔インタフェース

エンタプライズBeanの遠隔インタフェースの要件は,次のとおりとする。

6.10.6 エンタプライズBeanのホームインタフェース

エンタプライズBeanのホームインタフェースのシグネチャの要件は,次のとおりとする。

6.11 コンテナ提供者の責任

6.11では,セションBeanをサポートするコンテナ提供者の責任を示す。

6.11.1 実装クラスの生成

コンテナ提供者が提供するツールは,エンタプライズBeanの配置時に付加クラスを生成する責任をもつ。 ツールは,エンタプライズBean提供者が提供するクラス及びインタフェースを自己検査することによって, Beanの配置記述子から得られる情報から,付加クラスの生成のために必要な情報を得る。

コンテナツールは,次のクラスを生成しなければならない。

コンテナツールは,コンテナ固有のコードとエンタプライズBeanクラスとを混合するクラスを生成してもよい。 例えば,コードは,コンテナを支援して実行時にBeanインスタンスを管理してもよい。 ツールは,サブクラス化,委託及びコード生成を使用できる。

コンテナのツールは,同様に,業務メソッドをラップし,業務論理を既存の操作環境へのカスタム化のために使用する 付加的なコードの生成を可能としてもよい。例えば,AccountManagerBean上の関数debit に対応するラッパーは,借りた合計が一定限度を超えないことを検査してもよい。

6.11.2 EJBホームクラス

EJBホームクラスは,エンタプライズBeanのホームインタフェースを実装するコンテナの生成したクラスとする。 クラスは,インタフェースjavax.ejb.EJBHomeのメソッド及びエンタプライズBeanに固有のメソッドcreate() を実装する。

各メソッドcreate()の実装は,一致するejbCreate()を呼び出す。

インタフェースjavax.ejb.EJBHomeで定義されるメソッドremove()の実装は,(インスタンスが 受動状態にある場合には,)インスタンスを活性化し,そのインスタンス上でメソッドejbRemove() を呼び出さなければならない。

6.11.3 EJBオブジェクトクラス

EJBオブジェクトクラスは,エンタプライズBeanの遠隔インタフェースを実装するコンテナの生成したクラスとする。 EJBオブジェクトクラスは,インタフェースjavax.ejb.EJBObjectのメソッド及びエンタプライズBean に固有の業務メソッドを実装する。

(インタフェースjavax.ejb.EJBObjectで定義される)メソッドremove()の実装は,(インスタンスが 受動状態にある場合には,)インスタンスを活性化し,インスタンス上でメソッドejbRemove() を呼び出さなければならない。

各業務メソッドの実装は,(インスタンスが受動状態にある場合には,)インスタンスを活性化し, インスタンス上で一致する業務メソッドを呼び出さなければならない。

6.11.4 ハンドルクラス

コンテナは,エンタプライズBeanに対応するハンドルクラスを実装する責任をもつ。 ハンドルクラスは,Javaプログラム言語の直列化プロトコルによって直列化可能でなければならない。

6.11.5 メタデータクラス

コンテナは,クライアントのビュー契約にメタデータを提供するクラスを実装する責任をもつ。 クラスは,妥当なRMIのクラスValueでなければならず,インタフェースjavax.ejb.EJBMetaData を実装しなければならない。

6.11.6 再入不可能なインスタンス

コンテナは,確実に,一つのスレッドだけがいかなる時でも一つのインスタンスを実行可能としなければならない。 インスタンスが他の要求を実行している間に,クライアントの要求がインスタンスに到達した場合には, コンテナは,2番目の要求にjava.rmi.RemoteExceptionを投げなければならない。

セションエンタプライズBeanは,ただ一つのクライアントだけのサポートを意図されていることに注意。 そのために,二つのクライアントが同じセションBeanを呼び出そうとした場合には,アプリケーションエラーとなる。

この規則は,アプリケーションがセションBeanインスタンスにループバック呼出しをできないことを意味する。

6.11.7 トランザクション適用範囲,セキュリティ及び例外

コンテナは,11.,14.及び12.でそれぞれ示す,トランザクション適用範囲, セキュリティ検査及び例外処理に関する規則に従わなければならない。


目次 | |