BEA ホーム | 製品 | dev2dev | support | askBEA
TM TM
 ドキュメントのダウンロード   サイト マップ   Glossary 
検索

WebLogic エンタープライズ JavaBeans プログラマーズ ガイド

 Previous Next Contents Index PDF で侮ヲ  

WebLogic Server EJB コンテナとサポートされるサービス

以下の節では、WebLogic Server の EJB コンテナについて説明します。また、EJB の動作のさまざまな側面について、コンテナが提供する機能およびサービスとの関連から説明します。コンテナ管理による永続性 (CMP) の詳細については、WebLogic Server のコンテナ管理による永続性サービス,を参照してください。

 


EJB コンテナ

EJB コンテナは、デプロイ済み EJB を収容する実行時コンテナです。WebLogic Server の起動時に自動的に作成されます。EJB オブジェクトは、作成から削除まで、ライフサイクル全体に渡ってこのコンテナ内で動作します。EJB コンテナは、キャッシュ、同時実行性、永続性、セキュリティ、トランザクション管理、ロック、環境、メモリ レプリケーション、コンテナ内の EJB オブジェクトのクラスタ化などの標準のサービス集合を提供します。

1 つのコンテナに複数の Bean をデプロイできます。コンテナにデプロイされる個々のセッション Bean およびエンティティ Bean に対して、コンテナはホーム インタフェースを提供します。クライアントはホーム インタフェースを通じて、エンティティ Bean に属するエンティティ オブジェクトを作成、検索、および削除したり、特定のエンティティ Bean オブジェクトに固有でないホームのビジネス メソッドを実行することができます。クライアントは Java Naming and Directory Interface (JNDI) を使用して、または EJB 参照に従って (こちらのほうがより一般的)、エンティティ Bean のホーム インタフェースをルックアップできます。JNDI のネームスペース内でエンティティ Bean のホーム インタフェースを見つけられるようにするのはコンテナの役割です。JNDI を通じたホーム インタフェースのルックアップについて、詳しくは『WebLogic JNDI プログラマーズ ガイド』を参照してください。

 


EJB のライフサイクル

以降の節では、コンテナによるキャッシュ サービスのサポートに関する情報を示します。また、WebLogic Server での EJB インスタンスのライフサイクルを、WebLogic Server の視点から説明します。これらの節では EJB インスタンスという用語を使用しますが、これは EJB Bean クラスの実際のインスタンスという意味です。EJB インスタンスは、クライアント側から見た EJB の論理インスタンスを意味するものではありません。

エンティティ Bean のライフサイクルとキャッシュおよびプール

WebLogic Server は、エンティティ EJB のパフォーマンスとスループットを向上させるために、次の機能を提供します。

以降の節では、エンティティ Bean インスタンスのライフサイクル、コンテナがフリー プールおよびキャッシュを取得および管理する方法について説明します。 図 4-2 を参照してください。

エンティティ EJB インスタンスの初期化 (フリー プール)

initial-beans-in-free-pool にゼロ以外の値を指定すると、WebLogic Server では、起動時に、指定した数の Bean インスタンスがプール内に生成されます。

initial-beans-in-free-pool のデフォルト値はゼロです。 起動時に Bean インスタンスをフリー プールに格納しておくと、Bean に対する最初のリクエストが来たときに新しいインスタンスを生成せずに処理できるため、EJB の初期応答時間が短縮されます。

フリー プールからの Bean インスタンスの取得は、プールが空の場合でも常に成功します。 プールが空の場合は、新しい Bean インスタンスが作成されて返されます。

POOLED Bean は匿名のインスタンスで、ファインダやホーム メソッドに使用されます。 プールに格納できるインスタンスの最大数は、weblogic-ejb-jar.xmlmax-beans-in-free-pool 要素の値で指定されます。

READY および ACTIVE エンティティ EJB インスタンス (キャッシュ)

Bean のビジネス メソッドが呼び出されると、コンテナはプールからインスタンスを取得して ejbActivate を呼び出し、インスタンスはメソッド呼び出しを処理します。

READY インスタンスはキャッシュ内にあり、ID (関連付けられた主キー) を持っていますが、現在トランザクションに関与していません。 WebLogic では、READY エンティティ EJB インスタンスを、最長時間未使用 (LRU) の順序で保持します。 モニタ タブの [Current Beans in Cache] フィールドには、アクティブなまたは準備が整っている Bean の数が表示されます。

ACTIVE インスタンスは現在トランザクションに関与しています。 トランザクションが完了すると、インスタンスは READY になり、他の Bean でスペースが必要になるまでキャッシュに保持されます。

max-beans-in-cache の影響と、キャッシュで許可される主キーが同じインスタンスの数は、次節キャッシュのルールは同時方式によって異なるで説明されているように同時方式によって異なります。

キャッシュのルールは同時方式によって異なる

表 4-1 では、同時方式ごとに以下のことを示しています。

キャッシュからの Bean の削除

READY エンティティ EJB インスタンスは、他の Bean でスペースが必要になるとキャッシュから削除されます。 READY インスタンスがキャッシュから削除される場合、Bean の ejbPassivate が呼び出されて、コンテナは Bean をフリー プールに戻そうとします。

コンテナがインスタンスをフリー プールに返そうとするときに、プール内に max-beans-in-free-pool の数のインスタンスが既にある場合、インスタンスは破棄されます。

ACTIVE エンティティ EJB インスタンスは、参加しているトランザクションがコミットまたはロールバックするまで、キャッシュから削除されません。トランザクションがコミットまたはロールバックすると、インスタンスは READY になり、キャッシュから削除できるようになります。

エンティティ EJB のライフサイクルの遷移

図 4-2 では、EJB のフリー プールとキャッシュ、およびエンティティ Bean インスタンスのライフサイクルを通じて発生する遷移について示します。

図4-2 エンティティ Bean のライフサイクル


 


 


 


 


 

ステートレス セッション EJB のライフサイクル

WebLogic Server は、フリー プールを使用してステートレス セッション EJB のパフォーマンスとスループットを高めます。フリー プールには、非バインド ステートレス セッション EJB が格納されます。非バインド EJB インスタンスはステートレス セッション EJB クラスのインスタンスで、メソッド呼び出しを処理しません。

次の図に、WebLogic Server のフリー プールと、ステートレス EJB がフリー プールに出入りするプロセスを示します。点線は、WebLogic Server 側から見た EJB の「状態」を表しています。

図4-3 ステートレス セッション EJB のライフサイクルを示す WebLogic Server フリー プール

ステートレス セッション EJB インスタンスを初期化する

デフォルトでは、WebLogic Server には起動時にステートレス セッション EJB インスタンスは存在しません。クライアントが個々の Bean にアクセスすると、WebLogic Server は EJB の新しいインスタンスを初期化します。 ただし、WebLogic Server の起動時に非アクティブな EJB インスタンスを作成する場合、initial-beans-in-free-pool デプロイメント記述子要素を weblogic-ejb-jar.xml ファイルで指定します。

このようにしておけば、クライアントが EJB にアクセスしたときの初期応答時間を短縮できます。これは、Bean を初期化してからアクティブ化するのではなく、フリー プールから Bean をアクティブ化することによって、最初のクライアント リクエストを満足させることができるからです。 デフォルトでは、initial-beans-in-free-pool は 0 に設定されています。

注意: フリー プールの最大サイズは、max-beans-in-free-pool デプロイメント要素の値、使用可能メモリ、または実行スレッドの数によって制限されます。

ステートレス セッション EJB をアクティブ化およびプールする

ステートレス セッション EJB に対するメソッドを呼び出すと、WebLogic Server はフリー プールからインスタンスを取得します。EJB は、クライアントのメソッド呼び出しの間アクティブ状態になります。メソッドが完了すると、EJB のインスタンスはフリー プールに戻されます。WebLogic Server は各メソッドの呼び出し後にクライアントからステートレス セッション Bean を非バインドするので、クライアントが使用する実際の Bean クラスは呼び出しごとに異なります。

EJB クラスのすべてのインスタンスがアクティブで、max-beans-in-free-pool に達した場合、EJB クラスを要求する新しいクライアントは、アクティブ EJB がメソッド呼び出しを完了するまでブロックされます。 トランザクションがタイムアウトになった場合 (トランザクション非対応の呼び出しでは、5 分経過した場合)、WebLogic Server は、リモート クライアントに対しては RemoteException を、ローカル クライアントに対しては EJBException を送出します。

ステートフル セッション EJB のライフサイクル

WebLogic Server は、Bean インスタンスのキャッシュを使用してステートフル セッション EJB のパフォーマンスを高めます。キャッシュはメモリ内にアクティブな EJB インスタンスを格納することで、それらをクライアント リクエストに即座に使用できるようにしています。キャッシュには、クライアントによって現在使用されている EJB と最近使用されたインスタンスが格納されます。 キャッシュ内のステートフル セッション Bean は、特定のクライアントにバインドされます。

次の図に、WebLogic Server のキャッシュと、ステートフル EJB がキャッシュに出入りするプロセスを示します。

図4-4 ステートフル セッション EJB のライフサイクル


 

ステートフル セッション EJB の作成

WebLogic Server には起動時にステートフル セッション EJB インスタンスは存在しません。 クライアントがステートフル セッション Bean へのアクセスを開始する前に、Bean とのセッションで使用する新しい Bean インスタンスが作成されます。 セッションが終了すると、インスタンスは破棄されます。 セッションが進行中の間は、インスタンスはメモリにキャッシュされます。

ステートフル セッション EJB のパッシベーション

パッシベーションは、EJB の状態をディスク上で保持しつつキャッシュからその EJB インスタンスを削除するために WebLogic Server が使用するプロセスです。 パッシブ化されている EJB はメモリには存在せず、キャッシュに格納されているときのようにクライアント リクエストに応じて即座に使用することはできません。

EJB 開発者は、ejbPassivate() メソッドが呼び出されたときに、ステートフル セッション Bean が、WebLogic Server によってデータがシリアライズされてインスタンスのパッシベーションが行われるような状態に置かれるようにしなければなりません。 パッシベーションの間、WebLogic Server は transientであると宣言されていないフィールドをシリアライズしようとします。 このため、すべての非 transient フィールドがシリアライズ可能オブジェクト (Bean のリモートおよびホーム インタフェースなど) を表すようにしなければなりません。 EJB 2.1 では、許可されるフィールド タイプが指定されています。

パッシベーションの制御

ステートフル セッション Bean のパッシベーションを制御するルールは、Bean の cache-type 要素の値によって決まります。この要素の値は以下のいずれかです。

idle-timeout-seconds 要素と max-beans-in-cache 要素も、cache-type の値に基づいてパッシベーションと削除の動作に影響を与えます。

積極的なパッシベーション (LRU)

cache-typeLRU に設定してステートフル セッション Bean の積極的なパッシベーションをコンフィグレーションすると、コンテナは以下の動作を行います。

怠惰なパッシベーション (NRU)

cache-typeNRU に設定して怠惰なパッシベーションがコンフィグレーションされた場合、関連するシステムのオーバーヘッドが原因でコンテナは Bean のパッシベーションを回避します。キャッシュの不足が Bean のパッシベーションまたは積極的な削除の原因となる唯一のイベントです。

コンテナは以下のように動作します。

アイドル状態にある EJB の削除の防止

idle-timeout-seconds を 0 に設定すると、WebLogic Server は、ある期間、アイドル状態になっている EJB をもはや削除しません。しかし、キャッシュ リソースが不足状態になった場合、EJB のパッシベーションが行われる可能性は依然としてあります。

EJB のキャッシュ サイズの管理

キャッシュ サイズを管理してプロダクション環境のパフォーマンスを最適化する方法については、『WebLogic Server パフォーマンス チューニング ガイド』の「EJB キャッシュ サイズの設定」を参照してください。

パッシベーションされた Bean の永続ストア ディレクトリの指定

ステートフル セッション Bean のパッシベーションが行われると、その状態はファイル システム ディレクトリに格納されます。 各サーバ インスタンスは、パッシベーションされたステートフル セッション Bean の状態を格納するためのディレクトリを持ちます。このディレクトリは、永続ストア ディレクトリと呼ばれます。永続ストア ディレクトリには、パッシベーションされた Bean ごとに 1 つのサブディレクトリが格納されます。

永続ストア ディレクトリは、たとえば次のようにサーバ インスタンス ディレクトリにデフォルトで作成されます。

D:¥releases¥700¥bea¥user_domains¥mydomain¥myserver¥pstore¥

永続ストアのパスは次のとおりです。

RootDirectory¥ServerName¥persistent-store-dir

各要素の説明は次のとおりです。

永続ストア ディレクトリには、パッシベーションされた Bean ごとに、ハッシュ コードで名前が付けられたサブディレクトリが格納されます。 たとえば、上の例のパッシベーションされた Bean のサブディレクトリは次のようになります。

D:¥releases¥700¥bea¥user_domains¥mydomain¥myserver¥pstore¥14t89gex0m2fr

ステートフル セッション Bean への同時アクセス

EJB 2.0 仕様によると、ステートフル セッション EJB に同時アクセスすると RemoteException が送出されます。 ステートフル セッション EJB に関するこのアクセス制限は、EJB クライアントが WebLogic Server の内部にあるのかそれともリモートにあるのかに関係なく適用されます。 この制限を無効にして、同時呼び出しが可能なようにステートフル セッション Bean をコンフィグレーションするには、allow-concurrent-calls デプロイメント要素を設定します。

複数のサーブレット クラスがステートフル セッション EJB にアクセスする場合は、サーブレット クラスのインスタンスごとではなくサーブレット スレッドごとに独自のセッション EJB インスタンスを使用する必要があります。 同時アクセスを避けるために、JSP またはサーブレットはリクエスト スコープでステートフル セッションを使用できます。

 


エンティティ EJB に対する ejbLoad() と ejbStore() の動作

WebLogic Server は、ejbLoad() および ejbStore() への呼び出しを使用して、エンティティ EJB の永続フィールドを読み書きします。 デフォルトでは、WebLogic Server は ejbLoad()ejbStore() を次の手順で呼び出します。

  1. エンティティ EJB のトランザクションが開始されます。クライアントが明示的に新しいトランザクションを開始して Bean を呼び出すか、または WebLogic Server が Bean のメソッド トランザクション属性に従って新しいトランザクションを開始します。

  2. WebLogic Server は ejbLoad() を呼び出して、Bean の永続データの最新バージョンを基盤となるデータストアから読み出します。

  3. トランザクションがコミットすると、WebLogic Server は ejbStore() を呼び出して、永続フィールドを基盤となるデータベースに書き込みます。

こうした ejbLoad()ejbStore() の呼び出しという単純なプロセスにより、新しいトランザクションは常に EJB の最新の永続的データを使用し、コミット時には常にそのデータをデータベースに書き込むようになります。 しかし、環境によっては、パフォーマンス上の理由から ejbLoad()ejbStore() の呼び出しを制限することができます。 この場合、代わりに ejbStore() の呼び出しをより頻繁に行って、コミットされていないトランザクションの中間結果を参照することができます。

WebLogic Server には、ejbLoad()ejbStore() の動作をコンフィグレーションするためのデプロイメント記述子要素が weblogic-ejb-jar.xml および weblogic-cmp-rdbms-jar.xml ファイルに用意されています。

is-modified-method-name を使用した ejbStore() の呼び出しの制限 (EJB 1.1 のみ)

is-modified-method-name デプロイメント記述子要素は、EJB 1.1 のコンテナ管理永続性 (CMP) Bean だけに適用されます。 この要素は、 weblogic-ejb-jar.xml ファイルに入っています。WebLogic Server の CMP 実装では、CMP フィールドの変更が自動的に検出され、それらの変更だけが基盤のデータストアに書き込まれます。 Bean 管理の永続性 (BMP) では is-modified-method-name を使用しないことをお勧めします。 なぜなら、is-modified-method-name 要素と ejbstore メソッドの両方を作成しなければならないからです。

デフォルトでは、WebLogic Server は各トランザクションが正常に完了 (コミット) したときに ejbStore() を呼び出します。ejbStore() は、EJB の永続フィールドが実際に更新されたかどうかに関係なく、コミット時に呼び出され、その結果、DBMS が更新されます。WebLogic Server の is-modified-method-name 要素は、ejbStore() の不必要な呼び出しによってパフォーマンスが低下するような場合に使用します。

is-modified-method-name を使用するには、EJB プロバイダは最初に、永続データが更新されたときに WebLogic Server に「合図」を送る EJB メソッドを開発する必要があります。このメソッドは、EJB フィールドが 1 つも更新されなかった場合は「false」を、フィールドが更新された場合は「true」を返さなければなりません。

EJB プロバイダまたは EJB デプロイメント記述子は、次に is-modified-method-name 要素の値を使用して、このメソッドの名前を識別します。WebLogic Server は、トランザクションがコミットされると指定されたメソッド名を呼び出し、そのメソッドが「true」を返した場合にだけ ejbStore() を呼び出します。 この要素の詳細については、is-modified-method-nameを参照してください。

is-modified-method-name に関する警告

is-modified-method-name 要素を使用すると、ejbStore() の不必要な呼び出しを避けることによってパフォーマンスを高めることができます。しかし、いつ更新が行われたかを正確に識別することは、EJB 開発者にとっては負担が大きい作業です。 指定された is-modified-method-name が不正確なフラグを WebLogic Server に返した場合、データの完全性に関する問題が起こりかねず、多くの場合、こうした問題を追跡するのは困難です。

エンティティ EJB の更新内容がシステム内で失われたと思われる場合、まずどのような状況でもすべての is-modified-method-name 要素の値が「true」を返すように設定してください。 これにより、WebLogic Server のデフォルト ejbStore() 動作に戻すことができ、問題が解決する場合があります。

delay-updates-until-end-of-tx を使用した ejbStore() 動作の変更

デフォルトでは、WebLogic Server はトランザクションのすべての Bean の永続ストレージをトランザクションの完了 (コミット) 時にだけ格納します。 これにより、不必要な更新と ejbStore() の呼び出しの反復が回避され、一般にパフォーマンスが向上します。

データベースがアイソレーション レベルの READ_UNCOMMITTED を使用する場合、他のデータベース ユーザが継続中のトランザクションの中間結果を参照できるようにすることができます。こうしたケースでは、トランザクションの完了時にだけデータストアを更新するという WebLogic Server のデフォルト動作は不適切な場合があります。

デフォルト動作を無効にするには、delay-updates-until-end-of-tx デプロイメント記述子要素を使用します。 この要素は、weblogic-ejb-jar.xml ファイルで設定します。 この要素を「false」に設定すると、WebLogic Server はトランザクションの完了時ではなく各メソッド呼び出しの後に ejbStore() を呼び出します。

注意: delay-updates-until-end-of-tx を false に設定しても、各メソッド呼び出しの後にデータベース更新が「コミットされた」状態になるわけではありません。更新はデータベースに送信されるだけです。更新は、トランザクションの完了時にのみデータベースにコミットまたはロールバックされます。

 


EJB の同時方式

同時方式は、EJB コンテナがエンティティ Bean への同時アクセスをどのように管理するかを指定するものです。 Database オプションが WebLogic Server のデフォルトの同時方式ですが、その Bean でどのような同時アクセスが必要になるかによって、別のオプションを指定したくなるでしょう。WebLogic Serverでは次の同時方式オプションを提供しています。

同時方式オプション

説明

Exclusive

Bean がトランザクションに関連付けられている場合、キャッシュされたエンティティ EJB インスタンスを排他的にロックする。 EJB インスタンスに対するリクエストは、トランザクションが完了するまでブロックされる。このオプションは、WebLogic Server バージョン 3.1 〜 5.1 までのデフォルトのロック動作。

Database

エンティティ EJB に対するリクエストのロックを基盤のデータストアに委ねる。WebLogic Server は、独立したエンティティ Bean を割り当て、ロックとキャッシングをデータベースが処理できるようにする。 現在のデフォルト オプション。

Optimistic

トランザクションの実行中、EJB コンテナあるいはデータベースでロックを行わない。EJB コンテナはトランザクションをコミットする前に、そのトランザクションで更新したデータがどれも変化していないことを確認する。 更新データのどれかが変わっていた場合、EJB コンテナはトランザクションをロールバックする。

ReadOnly

読み込み専用エンティティ Bean のみで使用される。 トランザクションごとに新たなインスタンスをアクティブ化する。これにより、リクエストは並列処理される。WebLogic Server は、read-timeout-seconds パラメータを基に、ReadOnly Bean に対して ejbLoad() を呼び出す。

読み書き対応 EJB の同時方式

read-write EJB の場合、ExclusiveDatabase、および Optimistic 同時方式を使えます。WebLogic Server では、各トランザクションの最初に EJB データをキャッシュにロードするか、または、トランザクション間のキャッシュを使用した ejbStore() の呼び出しの制限のようになります。トランザクションが正常にコミットしたとき、WebLogic Server は ejbStore() を呼び出すか、または、is-modified-method-name を使用した ejbStore() の呼び出しの制限 (EJB 1.1 のみ)のようになります。

同時方式の指定

EJB で使用するロック メカニズムを指定するには、weblogic-ejb-jar.xmlconcurrency-strategy デプロイメント パラメータを設定します。 concurrency-strategy は個々の EJB レベルで設定するので、EJB コンテナ内でロック メカニズムが混在することがあります。

次のものは weblogic-ejb-jar.xml からの抜粋ですが、ある EJB に同時方式を設定する手順を示しています。 この XML コード例では、デフォルトのロック メカニズム、Database を指定しています。

図4-5 同時方式を指定する XML の例

<entity-descriptor>
<entity-cache>
...
<concurrency-strategy>Database</concurrency-strategy>
</entity-cache>
...
</entity-descriptor>

concurrency-strategy を指定しない場合、WebLogic Server はエンティティ EJB インスタンスに対してデータベース ロックを実行します。

それぞれの同時方式について、以降の節で説明します。

Exclusive 同時方式

WebLogic Server 5.1 および 4.5.1 では、Exclusive 同時方式がデフォルトでした。 このロック方式は、EJB データへのアクセスの信頼性を高め、ejbLoad() を不必要に呼び出して EJB インスタンスの永続フィールドをリフレッシュするのを防ぎます。しかし、排他的ロック メカニズムは、EJB のデータへの同時アクセスに対しては最良のモデルとはなりません。いったんクライアントが EJB インスタンスをロックすると、他のクライアントは、永続フィールドを読もうとしているだけであっても、EJB のデータからブロックされてしまうからです。

WebLogic Server の EJB コンテナは、エンティティ EJB インスタンスに対して排他的ロック メカニズムを使用します。クライアントが EJB または EJB メソッドをトランザクションに関与させると、WebLogic Server はそのトランザクションの間そのインスタンスを排他的にロックします。同じ EJB またはメソッドを要求する他のクライアントは、現在のトランザクションが完了するまでブロックされます。

Database 同時方式

Database 同時方式は WebLogic Server におけるデフォルトであり、EJB 1.1 と EJB 2.0 で推奨されているメカニズムです。データベース ロックによって、エンティティ EJB の同時アクセスの処理速度が向上します。WebLogic Server コンテナでは、ロック サービスを基盤となるデータベースに任せます。排他的ロックとは異なり、基盤データ ストアはより高い粒度で EJB データをロックでき、またデッドロックを検出することができます。

データベース ロック メカニズムでは、EJB コンテナが引き続きエンティティ EJB クラスのインスタンスをキャッシュします。しかし、コンテナはトランザクション間の EJB インスタンスの中間状態をキャッシュしません。 代わりに、WebLogic Server は、トランザクションの開始時に各インスタンスに対して ejbLoad() を呼び出して、最新の EJB データを取得します。続いて、データのコミット リクエストがデータベースに送られます。このためデータベースは、EJB データのロック管理とデッドロック検出をすべて処理します。

基盤となるデータベースにロックを任せることで、エンティティ EJB データへの同時アクセスのスループットを上げつつ、デッドロックの検出も実行できます。しかし、データベース ロックを使用するには、基盤となるデータベースのロック方式に関するより詳細な知識が必要となります。この結果、EJB の異なるシステム間での移植性が低下する可能性があります。

cache-between-transactions 要素を「true」に設定し、Optimistic ではなく Database 同時方式を使う場合、コンパイラから cache-between-transactions を無効にすべきであることを伝える警告メッセージが返されます。 この条件が揃っている場合、WebLogic Server は cache-between-transactions を自動的に無効にします。

Optimistic 同時方式

Optimistic 同時方式は、トランザクションの実行中、EJB コンテナまたはデータベースでどのようなロックも行いません。このオプションを指定した場合、EJB コンテナはあるトランザクションが更新したデータに変更がないことを確かめます。トランザクションのコミット前にフィールドをチェックするという手段によって、「効率的な更新」を実行します。

注意: Optimistic 同時方式の場合、EJB コンテナは Blob/Clob フィールドをチェックしません。 これを回避するには、バージョン チェックまたはタイムスタンプ チェックを行います。

Optimistic 同時方式の制限

Optimistic 同時方式を使用する場合は、weblogic-cmp-jar.xmlinclude-updates 要素を false に設定することをお勧めします。 include-updatestrue に設定して Optimistic 同時方式を使用すると、ペシミスティックな同時方式を使用するのと同じことになり、効果がありません。 include-updatestrue に設定する必要がある場合は、Database 同時方式を使用してください。

include-updatestrue に設定して Optimistic 同時方式を使用するのは、トランザクション中にロックするデータベース (Oracle 以外のデータベース) ではサポートされません。オプティミスティックなトランザクションでは、ローカル トランザクションを使用して読み込みを行い、トランザクションの終了までロックすることを避けるためです。 ただし、オプティミスティックなトランザクションでは、必要に応じて更新をロールバックできるように、現在の JTA トランザクションを使用して書き込みを行います。 一般に、JTA トランザクションで行われる更新は、その JTA トランザクションがコミットされるまで、読み込みトランザクションからは見えません。

Optimistic 同時方式におけるデータの有効性のチェック

トランザクションによるデータの読み込みや更新が、別のトランザクションによって変更されていないことを確認するために、トランザクションをコミットする前に Optimistic 同時方式の Bean のトランザクション データを検証するように、EJB コンテナをコンフィグレーションできます。 変更されたデータを検出した場合、EJB コンテナはトランザクションをロールバックします。

注意: EJB コンテナは、Optimistic 同時方式の Bean では、Blob または Clob フィールドを検証しません。 これを回避するには、バージョン チェックまたはタイムスタンプ チェックを行います。

オプティミスティックなチェックのコンフィグレーション

Optimistic 同時方式の Bean の妥当性チェックは、weblogic-cmp-jar.xmltable-name スタンザの verify-columns 要素を使用してコンフィグレーションします。

Optimistic 同時方式を使用する場合は、verify-columns 要素によって、テーブル カラムの妥当性がどのようにチェックされるのかが指定されます。

  1. verify-columns 要素の値を以下のいずれかの値に指定します。

EJB コンテナはバージョンまたはタイムスタンプ カラムを管理して、トランザクションの完了時にその値を適切に更新します。

注意: バージョン カラムまたはタイムスタンプ カラムは、トランザクションで通常の CMP または CMR フィールドが変更されなかった場合は更新されません。トランザクションで変更された唯一のデータがバージョンまたはタイムスタンプ カラムの値だった場合 (トランザクションの開始の結果として)、トランザクションの最後にオプティミスティックなチェックで使用するカラムは更新されません。

  1. verify-columnsVersion または Timestamp に設定されている場合は、weblogic-cmp-jar.xml ファイルの table-map スタンザの optimistic-column を使用してバージョンまたはタイムスタンプ カラムを指定します。 このカラムを cmp-field にマップするかは任意です。

    optimistic-column 要素では、Optimistic 同時方式を実装するためのバージョン値またはタイムスタンプ値を格納するデータベース カラムを指定します。 すべてのデータベースが大文字と小文字を区別するわけではありませんが、この要素では大文字と小文字を区別します。 この要素の値は、verify-columnsVersion または Timestamp に設定されている場合を除いて無視されます。

EJB が複数のテーブルにマップされる場合、トランザクション中に更新したテーブルに対してのみオプティミスティックなチェックが実行されます。

デフォルトでは、オプティミスティックな Bean ではトランザクション間のキャッシングは有効でありません。 明示的に有効にする必要があります。 トランザクション間のキャッシュを使用した ejbStore() の呼び出しの制限を参照してください。 Optimistic 同時方式のエンティティ Bean で長期キャッシングを有効にした場合、EJB コンテナは前回のトランザクションでキャッシュされた値を再利用します。 コンテナは、トランザクションの最後にオプティミスティックに競合をチェックすることによって、更新におけるトランザクションの一貫性を保証します。 また、オプティミスティックな競合を回避し、キャッシュされたデータの鮮度が維持されるように、オプティミスティックなデータ更新に関する通知が他のクラスタ メンバーにブロードキャストされます。

オプティミスティックなチェックと Oracle データベース

Oracle データベースで、CMP の非キー フィールドの型が java.util.Date で、実装の型が Oracle DATE であるエンティティ EJB に対して、verify-columnsModified に設定する場合、非キー DATE フィールドに対して単純な更新が行われると、そのレコードを更新しているのが 1 ユーザのみの場合でも、WebLogic Server はオプティミスティックな同時方式違反の例外を送出します。

この問題は、Oracle DATE カラムと java.util.Date 型とのデータ値の精度の不一致が原因で発生します。 java.util.Date 型はミリ秒単位ですが、Oracle DATE カラムはミリ秒単位ではありません。 このエラーを回避するには 2 つの方法があります。

ReadOnly 同時方式

WebLogic Server では、読み込み専用エンティティ Bean に対する同時アクセスをサポートしています。この同時方式では、トランザクションごとに 1 つの読み込み専用エンティティ Bean インスタンスをアクティブ化することでリクエストを並行に処理できるようにします。

WebLogic Server 7.0 より前は、読み込み専用エンティティ Bean には排他的ロック同時方式が用いられていました。 この方式では、Bean がトランザクションに関連付けられている場合、キャッシュされたエンティティ Bean インスタンスを排他的にロックします。このエンティティ Bean に対する他のリクエストは、トランザクションが完了するまでブロックされます。

データベースからの読み込みを避け、WebLogic Server では キャッシュ中の既存インスタンスからEJB 2.0 CMP Bean の状態をコピーします。 このリリースでは、ReadOnly オプションが読み込み専用エンティティ Bean のデフォルトの同時方式です。

アプリケーションレベルまたはコンポーネントレベルにおいて、読み込み専用エンティティ Bean のキャッシングを指定することができます。

読み込み専用エンティティ Bean のキャッシングを有効にするには、次の手順に従います。

  1. JAR ファイルまたは EAR ファイルに対し、concurrency-strategy デプロイメント記述子要素で ReadOnly オプションを指定します。

  2. デプロイメント記述子を指定する手順については、EJB デプロイメント記述子の指定と編集を参照してください。

読み込み専用エンティティ Bean と ReadOnly 同時方式

以前のバージョンの読み込み専用エンティティ Bean は、このバージョンの WebLogic Server で機能します。 以前のバージョンと同じように、weblogic-ejb-jar.xmlread-timeout-seconds 要素を設定できます。 EJB の同時方式が ReadOnly で、read-timeout-seconds が設定されている場合、読み込み専用 Bean が呼び出されると、キャッシュのデータが read-timeout-seconds の設定より古いかどうかが WebLogic Server によってチェックされます。 古い場合は、Bean の ejbLoad が呼び出されます。それ以外の場合は、キャッシュされているデータが使用されます。

ReadOnly 同時方式の制限

read-only 同時方式を使用するエンティティ EJB は、以下の制限に従わなければなりません。

読み込み専用マルチキャストの無効化

読み込み専用マルチキャストを無効化すると、キャッシュされたデータを効率的に無効にできます。

読み込み専用エンティティ Bean を無効にするには、CachingHome または CachingLocalHome インタフェースの次の invalidate() メソッドを呼び出します。

図4-6 CachingHome インタフェースと CachingLocalHome インタフェースを示すコード例

package weblogic.ejb;
public interface CachingHome {
	public void invalidate(Object pk) throws RemoteException;
public void invalidate (Collection pks) throws RemoteException;
public void invalidateAll() throws RemoteException;
public interface CachingLocalHome {
	public void invalidate(Object pk) throws RemoteException;
public void invalidate (Collection pks) throws RemoteException;
public void invalidateAll() throws RemoteException
}

次のコード例は、ホームを CachingHome にキャストしてからメソッドを呼び出す方法を示したものです。

図4-7 ホームをキャストしてからメソッドを呼び出す方法を示すコード例

import javax.naming.InitialContext; 
import weblogic.ejb.CachingHome;
Context initial = new InitialContext(); 
Object o = initial.lookup("CustomerEJB_CustomerHome");
CustomerHome customerHome = (CustomerHome)o;
CachingHome customerCaching = (CachingHome)customerHome; 
customerCaching.invalidateAll();

invalidate() メソッドを呼び出すと、読み込み専用エンティティ Bean はローカル サーバで無効化され、マルチキャスト メッセージがクラスタ内の他のサーバに送信されてキャッシュされているその Bean のコピーが無効化されます。 無効化された読み込み専用エンティティ Bean を次に呼び出すと、ejbLoad が呼び出されます。 ejbLoad() は、最新の永続的データを基盤となるデータストアから読み出します。

WebLogic Server は、トランザクションの更新が完了してから invalidate() メソッドを呼び出します。トランザクションの更新中に無効化処理が行われた場合、アイソレーション レベルでコミットされていないデータの読み出しが許可されていないと、更新前のデータが読み出される可能性があります。

read-mostly パターン

WebLogic Server は、weblogic-ejb-jar.xml に設定される read-mostly キャッシュ方式をサポートしていません。 しかし、頻繁に更新されない EJB データがある場合、read-only EJB と read-write EJB を組み合わせることによって、「read-mostly パターン」を作成できます。

詳細については、WebLogic Server の配布キットの次の場所にある read-mostly のサンプルを参照してください。

%SAMPLES_HOME%/server/config/examples/ejb/extensions/readMostly

WebLogic Server は、read-mostly パターンの自動 invalidate() メソッドを提供します。このパターンでは、読み込み専用エンティティ Bean と読み書き対応エンティティ Bean が同じデータにマップされます。データを読み出すには読み込み専用エンティティ Bean を使用し、データを更新するには読み書き対応エンティティ Bean を使用します。

read-mostly パターンでは、read-only エンティティ EJB は、weblogic-ejb-jar.xml ファイルの read-timeout-seconds デプロイメント記述子要素によって指定されている間隔で Bean データを取得します。 別の read-write エンティティ EJB は、その read-only EJB と同じデータをモデル化し、必要な間隔でそのデータを更新します。

read-mostly パターンを作成する場合、以下の注意に従って、データの一貫性に関する問題が発生しないようにしてください。

注意: WebLogic Server クラスタでは、read-only EJB のクライアントは、キャッシュされた EJB データを使用することで恩恵を受けることができます。 read-write EJB のクライアントは、真のトランザクション動作から恩恵を受けることができます。これは、read-write EJB の状態が常に基盤データベース上のそのデータの状態と一致するからです。 詳細については、クラスタ内のエンティティ EJBを参照してください。

 


エンティティ Bean の組み合わせキャッシング

組み合わせキャッシングを使用すると、同じ J2EE アプリケーション内の複数エンティティ Bean 間で 1 つの実行時キャッシュを共有できます。これまでは、アプリケーションの一部であるエンティティ Bean それぞれに対し、別々のキャッシュをコンフィグレーションする必要がありました。このことは、エンティティ Bean ごとにキャッシュをコンフィグレーションするのに時間がかかること、アプリケーションの実行により多くのメモリが必要になるなど、利便性やパフォーマンスの点で若干の問題を招いていました。この機能は、それらの問題解決に役立ちます。

アプリケーションレベルのキャッシュをコンフィグレーションするには、次の手順に従います。

  1. weblogic-application.xml ファイルが EAR ファイルのMETA-INF ディレクトリ内にあるか確めます。

  2. weblogic-application.xml ファイルに次のように入力します。
    <weblogic-application>
    <ejb>
    <entity-cache>
    <entity-cache-name>large_account</entity-cache-name>
    <max-cache-size>
    <megabytes>1</megabytes>
    </max-cache-size>
    </entity-cache>
    </ejb>
    </weblogic_application>

    entity-cache 要素を使用して、実行時にエンティティ Bean インスタンスをキャッシュする、名前付きのアプリケーションレベル キャッシュを定義します。各キャッシュを何個のエンティティ Bean が参照するかについて制限はありません。

    entity-cache のサブ要素は、 weblogic-ejb-jar.xml デプロイメント記述子ファイルで使われるのと同じ基本的意味を持っています。

  3. weblogic-ejb-jar.xml ファイルの entity-descriptor 要素を指定します。

    entity-descriptor 要素を使用し、エンティティ Bean がアプリケーションレベルのキャッシュを使用するようにコンフィグレーションします。

デプロイメント記述子を指定する手順については、EJB デプロイメント記述子の指定と編集を参照してください。

weblogic-application.xml デプロイメント記述子については、『WebLogic Server アプリケーションの開発』の「application.xml デプロイメント記述子の要素」に詳細な説明があります。

 


トランザクション間のキャッシング

トランザクション間のキャッシング、または、長期キャッシングを使用すると、EJB コンテナはエンティティ Bean の永続データをトランザクション間でキャッシュできるようになります。エンティティ Bean に関してトランザクション間のキャッシングを設定できるかどうかは、以下の 3 つの表にまとめてあるように、同時方式によって決まります。

表4-1 BMP Bean に関して各同時方式で許可される cache-between-transactions の値

BMP Bean が使用する同時方式

設定可能な cache-between-transactions の値

Database

False のみ

Exclusive

True または False

Read-Only

True または False

Optimistic

該当なし。 Optimistic 同時方式は BMP Bean では使用できない。


 

表4-2 CMP 2.0 Bean に関して各同時方式で許可される cache-between-transactions の値

CMP 2.0 Bean が使用する同時方式

設定可能な cache-between-transactions の値

Database

True のみ

Exclusive

True または False

Read-Only

True または False

Optimistic

True または False


 

表4-3 CMP 1.1 Bean に関して各同時方式で許可される cache-between-transactions の値

CMP 1.1 Bean が使用する同時方式

設定可能な cache-between-transactions の値

Database

True のみ

Exclusive

True または False

Read-Only

True または False

Optimistic

該当なし。 Optimistic 同時方式は CMP 1.1 Bean では使用できない。


 

Exclusive 同時方式でのトランザクション間のキャッシング

Exclusive 同時方式のエンティティ Bean で長期キャッシングを有効にする場合、EJB コンテナは基盤データへの更新アクセスを排他的にする必要があります。これはつまり、その EJB コンテナ以外の別のアプリケーションがデータを更新してはならないということです。あるクラスタ内に Exclusive 同時方式の EJB をデプロイする場合、長期キャッシングは自動的に無効になります。クラスタ内のどのノードからもデータを更新できるからです。これにより長期キャッシングは実行不能になります。

WebLogic Server の旧バージョンでは、この機能は weblogic-ejb-jar.xml の db-is-shared 要素によって制御されていました。

注意: Exclusive 同時方式は単一サーバでの機能です。クラスタ化されたサーバでは使用しないでください。

ReadOnly 同時方式でのトランザクション間のキャッシング

ReadOnly 同時方式のエンティティ Bean で長期キャッシングを無効にした場合、EJB コンテナでは読み込み専用データの長期キャッシングを常に実行するので、cache-between-transactions の設定値は無視されます。

Optimistic 同時方式でのトランザクション間のキャッシング

Optimistic 同時方式のエンティティ Bean で長期キャッシングを有効にした場合、EJB コンテナは前回のトランザクションでキャッシュされた値を再利用します。コンテナは、トランザクションの最後にオプティミスティックに競合をチェックすることによって、更新におけるトランザクションの一貫性を保証します。 オプティミスティックなチェックを設定する手順については、Optimistic 同時方式を参照してください。

また、オプティミスティックな競合を回避できるように、オプティミスティックなデータ更新に関する通知が他のクラスタ メンバーにブロ―ドキャストされます。

トランザクション間のキャッシングの有効化

トランザクション間のキャッシングを有効にするには、次の手順に従います。

  1. 次のオプションの 1 つを選択し、weblogic-ejb-jar.xml ファイルの cache-between-transactions 要素を設定します。

  2. デプロイメント記述子を指定する手順については、EJB デプロイメント記述子の指定と編集を参照してください。

トランザクション間のキャッシュを使用した ejbStore() の呼び出しの制限

デフォルトによって、WebLogic Server は各トランザクションの開始時に ejbLoad() を呼び出します。この動作は、複数のソースがデータベースを更新するような環境に適しています。 複数のクライアント (WebLogic Server を含む) が EJB の基盤データを変更する可能性があるため、ejbLoad() の最初の呼び出しは、キャッシュ済みデータを更新する必要があることを Bean に通知し、確実に最新のデータが処理対象になるようにします。

クラスタではなく単一のサーバで Exclusive 同時方式を使用する場合のように、単一の WebLogic Server トランザクションのみが特定の EJB に同時アクセスするような特殊な環境では、ejbLoad() をデフォルトで呼び出す必要はありません。EJB の基盤データを更新するクライアントまたはシステムは他に存在しないので、WebLogic Server の EJB データのキャッシュは常に最新のものとなります。 こうしたケースでは、ejbLoad() を呼び出しても、Bean にアクセスする WebLogic Server クライアントに対して余計なオーバーヘッドが発生するだけです。

単一の WebLogic Server トランザクションが特定の EJB にアクセスする場合、ejbLoad() の不要な呼び出しを避けるために、WebLogic Server には cache-between-transactions デプロイメント パラメータが用意されています。 デフォルトでは、cache-between-transactions は各 EJB に対して Bean の weblogic-ejb-jar.xml ファイルで「false」に設定されています。このため、ejbLoad() は各トランザクションの開始時に必ず呼び出されます。 単一の WebLogic Server トランザクションだけが EJB の基盤データにアクセスするようなケースでは、その Bean の weblogic-ejb-jar.xml ファイルの d を「true」に設定できます。 cache-between-transactions を「true」に設定して EJB をデプロイすると、WebLogic Server の単一のインスタンスが以下の場合に限り、その Bean の ejbLoad() を呼び出します。

cache-between-transactions に関する制限

cache-between-transactions には以下の制限があります。

単一サーバ デプロイメントでは、cache-between-transactions は、Exclusive、Optimistic、および Read-Only 同時方式でのみ有効にできます。Database 同時方式では cache-between-transactions を使用できません。

クラスタ デプロイメントでは、cache-between-transactions は、Optimistic および Read-Only 同時方式でのみ有効にできます。Exclusive または Database 同時方式では cache-between-transactions を使用できません。

 


WebLogic Server クラスタにおける EJB

この節では EJB のクラスタ化のサポートについて説明します。

クラスタ化されたホームおよび EJBObject

WebLogic Server クラスタ内の EJB は、ホーム オブジェクトと EJB オブジェクトという 2 つの主要構造を修正したものを使用します。 単一サーバ (非クラスタ化) 環境では、クライアントは EJB のホーム インタフェースを通じて EJB をルックアップします。ホーム インタフェースの背後には、対応するホーム オブジェクトがサーバ上に存在します。Bean の参照後、クライアントはリモート インタフェースを通じてその Bean のメソッドと対話します。リモート インタフェースの背後には、EJB オブジェクトがサーバ上に存在します。

次の図は、単一サーバ環境での EJB の動作を示しています。

図4-8 単一サーバの動作


 

注意: EJB のフェイルオーバは、リモートクライアント と EJB との間でのみ機能します。

クラスタ化された EJB ホーム オブジェクト

すべての EJB タイプ (ステートレス セッション EJB、ステートフル セッション EJB、およびエンティティ EJB) は、クラスタ対応のホーム スタブを持つことができます。 クラスタ対応のホーム スタブを作成するかどうかは、weblogic-ejb-jar.xmlhome-is-clusterable デプロイメント記述子要素によって決定されます。

EJB がクラスタにデプロイされると、そのホームはクラスタワイドのネーミング サービスにバインドされます。 各サーバではそのホームのインスタンスを同じ名前でバインドできます。 クライアントがこのホームをルックアップすると、そのクライアントでは Bean がデプロイされた各サーバ上のホームへの参照を持つレプリカ対応スタブが取得されます。 create() または find() が呼び出されると、その呼び出しはレプリカ対応スタブによってレプリカの 1 つに転送されます。 ホームのレプリカは、find() の結果を受信するか、またはそのサーバで Bean のインスタンスを作成します。

クラスタ化されたホーム スタブは、EJB ルックアップ リクエストを使用可能なサーバに分散することでロード バランシングを実現します。また、他のサーバに障害が発生したときにルックアップ リクエストを使用可能なサーバに転送することで、それらのリクエストのフェイルオーバもサポートします。

クラスタ化された EJBObject

WebLogic Server クラスタでは、EJBObject のサーバサイド表現は、レプリカ対応の EJBObject スタブによって置き換えることができます。 このスタブは、クラスタ内のサーバに存在する EJBObject のすべてのコピーに関する知識を保持します。 EJBObject スタブは、EJB メソッド呼び出しに対するロード バランシングおよびフェイルオーバを提供します。 たとえば、クライアントが特定の WebLogic Server に対して EJB メソッドを呼び出したが、そのサーバがダウンしている場合、EJBObject スタブはそのメソッド呼び出しを稼働中の別のサーバにフェイルオーバします。

EJB がレプリカ対応 EJBObject スタブを利用するかどうかは、デプロイされている EJB のタイプと、エンティティ EJB の場合、デプロイメント時に選択した同時方式によって決まります。 詳細については、さまざまなタイプの EJB に対するクラスタ化のサポートを参照してください。

さまざまなタイプの EJB に対するクラスタ化のサポート

次の節では、セッション EJB とエンティティ EJB に対するクラスタ化のサポートについて説明します。

クラスタ内のステートレス セッション EJB

ステートレス セッション EJB は、クラスタ対応のホーム スタブとレプリカ対応の EJBObject スタブの両方を持つことができます。デフォルトによって、WebLogic Server は EJB メソッド呼び出しに対するフェイルオーバ サービスを提供しますが、これは障害がメソッド呼び出しの合間に発生した場合に限ります。たとえば、メソッドの完了後に障害が発生した場合や、メソッドがサーバに接続されなかった場合などには、フェイルオーバが自動的にサポートされます。しかし、EJB メソッドの実行中に障害が発生した場合、WebLogic Server は別のサーバにそのメソッドを自動的にフェイルオーバしません。

このデフォルト動作では、EJB メソッド内のデータベース更新がフェイルオーバによって「重複」することはありません。たとえば、データストア内のある値をインクリメントするメソッドをクライアントが呼び出し、そのメソッドが完了する前に WebLogic Server が別のサーバにフェイルオーバした場合、クライアントの 1 度のメソッド呼び出しによってデータベースが 2 度更新されることになります。

繰り返し呼び出しても更新が重複しないように記述されたメソッドを、「多重呼び出し不変」と呼びます。 WebLogic Server には、多重呼び出し不変のメソッド用に 2 種類の weblogic-ejb-jar.xml デプロイメント プロパティ (一方は Bean レベル、もう一方はメソッド レベル) が用意されています。

Bean レベルでは、stateless-bean-methods-are-idempotent を「true」に設定した場合、WebLogic Server はメソッドが多重呼び出し不変であると見なして、メソッド呼び出し中に障害が発生した場合でも、EJB メソッドに対するフェイルオーバ サービスを提供します。

メソッド レベルでは、idempotent-methods デプロイメント プロパティを使用して同じことを実行できます。

<idempotent-methods>
<method>
<description>...</description>
<ejb-name>...</ejb-name>
<method-intf>...</method-intf>
<method-name>...</method-name>
<method-params>...</method-params>
</method>
</idempotent-methods>

次の図は、WebLogic Server クラスタ環境でのステートレス セッション EJB の動作を示しています。

図4-9 クラスタ化されたサーバ環境でのステートレス セッション EJB

クラスタ内のステートフル セッション EJB

ステートフル セッション EJB でクラスタ対応のホーム スタブを利用できるようにするには、home-is-clusterable を「true」に設定します。これにより、ステートフル EJB ルックアップに対するフェイルオーバとロード バランシングが提供されます。このようにコンフィグレーションされたステートフル セッション EJB は、レプリカ対応の EJBObject スタブを利用できます。 ステートフル セッション EJB のインメモリ レプリケーションの詳細については、ステートフル セッション EJB のインメモリ レプリケーションを参照してください。

注意: ロード バランシングとフェイルオーバについては、『WebLogic Server クラスタ ユーザーズ ガイド』で詳しく説明されています。 次の 3 つの節を参照してください。「EJB と RMI オブジェクト」、「EJB と RMI オブジェクトのロード バランシング」、「EJB と RMI のレプリケーションとフェイルオーバ」。

ステートフル セッション EJB のインメモリ レプリケーション

WebLogic Server EJB コンテナは、ステートフル セッション EJB 向けのクラスタ化をサポートします。 WebLogic Server 5.1 では、EJBHome オブジェクトだけがステートフル セッション EJB 用にクラスタ化されますが、EJB コンテナは、EJB の状態をクラスタ化された WebLogic Server インスタンスの間でレプリケートできます。

ステートフル セッション EJB のレプリケーション サポートは、EJB クライアントには見えません。 ステートフル セッション EJB がデプロイされると、WebLogic Server はそのステートフル セッション EJB 用にクラスタ対応の EJBHome スタブとレプリカ対応の EJBObject スタブを作成します。 EJBObject スタブは、EJB インスタンスが動作するプライマリ WebLogic Server インスタンスと、その Bean の状態をレプリケートするためのセカンダリ WebLogic Server のリストを保持します。

EJB のクライアントがその EJB の状態を変更するトランザクションをコミットするたびに、WebLogic Server はその EJB の状態をセカンダリ サーバ インスタンスにレプリケートします。Bean の状態のレプリケーションは直接メモリ内で行われるため、クラスタ化された環境で最高のパフォーマンスを得られます。

プライマリ サーバ インスタンスがダウンした場合、クライアントの次のメソッド呼び出しはセカンダリ サーバの EJB インスタンスに自動的に転送されます。セカンダリ サーバは、その EJB インスタンスのプライマリ WebLogic Server となり、新しいセカンダリ サーバが別のフェイルオーバに対応します。EJB のセカンダリ サーバがダウンした場合、WebLogic Server はクラスタから新しいセカンダリ サーバ インスタンスを使用します。

このため、ステートフル セッション EJB のクライアントは EJB の最後にコミットされた状態に迅速にアクセスできます。ただし、後述のインメモリ レプリケーションの制限事項で挙げる特殊な環境は除きます。 レプリケーション グループの使い方の詳細については、「レプリケーション グループを使用する」を参照してください。

インメモリ レプリケーションの要件とコンフィグレーション

WebLogic Server クラスタでステートフル セッション EJB の状態をレプリケートするには、クラスタの EJB クラスを同種にする必要があります。つまり、同じデプロイメント プロパティを使用して、クラスタ内のすべての WebLogic Server インスタンスに同じ EJB クラスをデプロイしなければなりません。異種クラスタに対するインメモリ レプリケーションはサポートされていません。

デフォルトでは、WebLogic Server はクラスタ内でステートフル セッション EJB をレプリケートしません。これは、WebLogic Server バージョン 6.0 でリリースされた動作をモデル化したものです。 レプリケーションを有効にするには、weblogic-ejb-jar.xml デプロイメント ファイルの replication-type デプロイメント パラメータを InMemory に設定します。

図4-10 レプリケーションを有効にする XML の例

<stateful-session-clustering>
...
<replication-type>InMemory</replication-type>
</stateful-session-clustering>

インメモリ レプリケーションの制限事項

ステートフル セッション EJB の状態をレプリケートすることによって、プライマリ WebLogic Server インスタンスがダウンした場合でも、一般にクライアントは EJB の最後にコミットされた状態を取得できます。しかし、次のフェイルオーバのシナリオでは、最後にコミットされた状態を取得できないこともまれにあります。

クラスタ内のエンティティ EJB

すべての EJB と同様に、エンティティ EJB は、home-is-clusterable を「true」に設定することによって、クラスタ対応のホーム スタブを利用できます。

EJBObject スタブの動作は、weblogic-ejb-jar.xmlconcurrency-strategy デプロイメント要素によって決まります。 concurrency-strategyRead-Write または Read-Only に設定できます。 デフォルト値は Read-Write です。

詳細については、以下の節を参照してください。

クラスタ内の読み込み専用エンティティ EJB

ホームで読み込み専用エンティティ Bean が検索または作成される場合は、レプリカ対応の EJBObject スタブが返されます。 このスタブでは、すべての呼び出しでロード バランシングが行われますが、回復可能な呼び出しエラーが発生したときに自動的にフェイルオーバは行われません。 読み込み専用 Bean は、データベース読み込みを防止するためにすべてのサーバでキャッシュされます。

クラスタ内の読み書き対応エンティティ EJB

ホームで読み書き対応エンティティ Bean が検索または作成される場合は、ローカル サーバでインスタンスが取得され、そのサーバに固定された EJBObject スタブが返されます。 ロード バランシングとフェイルオーバはホームのレベルでのみ行われます。 クラスタにはエンティティ Bean の複数のインスタンスが存在する可能性があるため、各インスタンスは各トランザクションの前にデータベースから読み込まれ、各コミットで書き込まれなければなりません。

クラスタ内の read-write エンティティ EJB は、以下のとおり、非クラスタ化システム内のエンティティ EJB と同じように動作します。

図 4-11 では、WebLogic Server クラスタ環境での読み書き対応エンティティ EJB の動作を示しています。ホーム スタブ上の 3 つの矢印は 3 つのサーバすべてを指し、複数のクライアント アクセスを示しています。

図4-11 クラスタ化されたサーバ環境の読み書き対応エンティティ EJB

注意: 上の図では、ホーム スタブを起点とする矢印はいずれも各サーバの EJBHome を指しています。

読み書き対応エンティティ EJB は、home-is-clusterable が true に設定されている場合に、安全な例外に関して自動フェイルオーバをサポートします。たとえば、メソッドの完了後に障害が発生した場合や、メソッドがサーバに接続されなかった場合などには、フェイルオーバが自動的にサポートされます。

クラスタ アドレス

クラスタをコンフィグレーションする際に、クラスタ内の管理対象サーバを識別するクラスタ アドレスを入力します。クラスタ アドレスは、URL のホスト名部分を構築するためにエンティティ Bean およびステートレス Bean で使用されます。クラスタ アドレスが設定されていない場合、EJB ハンドルは正しく動作しません。 クラスタ アドレスの詳細については、『WebLogic Server クラスタ ユーザーズ ガイド』を参照してください。

 


トランザクション管理

以降の節では、EJB コンテナによるトランザクション管理サービスのサポートについての情報を示します。いくつかのトランザクション シナリオを通して EJB を説明していきます。分散トランザクション (複数のデータストアで更新を行うトランザクション) に関与する EJB は、トランザクションのすべてのブランチが論理単位としてコミットまたはロールバックされることを保証します。

WebLogic Server の現行バージョンは、Java Transaction API (JTA)をサポートしています。 JTA は、分散トランザクション対応アプリケーションの実装に使用できます。

また、1.1 と 2.0 のどちらの EJB の場合でも 2 フェーズ コミットがサポートされています。2 フェーズ コミット プロトコルは、複数のリソース マネージャにまたがって 1 つのトランザクションを調整する手段です。これにより、トランザクションによる更新を関連データベースのすべてにコミットするか、またはすべてのデータベースから完全にロールバックし、トランザクションによる状態の前の状態に戻すことで、データの完全性が保証されます。

トランザクション管理の責任範囲

セッション EJB は、自身のコード、そのクライアントのコード、または WebLogic Server コンテナに基づいてトランザクション境界を定義できます。EJB は、コンテナまたはクライアントによって定められたトランザクション境界を使用できます。しかし、一定の制限に従わない限り、独自のトランザクション境界を定義することはできません (11.2.5)。

注意: EJB プロバイダが ejb-jar.xml ファイルにメソッドのトランザクション属性を指定しない場合、WebLogic Server はデフォルトで supports 属性を使用します。

トランザクション イベントのシーケンスは、コンテナ管理のトランザクションと Bean 管理のトランザクションで異なります。

javax.transaction.UserTransaction の使い方

EJB またはクライアント コードにトランザクション境界を定義するには、Java Transaction Service (JTS) または JDBC データベース接続を取得する前に、UserTransaction オブジェクトを取得してトランザクションを開始しなければなりません。 UserTransaction オブジェクトを取得するには、次のコマンドを使用します。

ctx.lookup("javax.transaction.UserTransaction");

データベース接続を取得してからトランザクションを開始した場合、その接続は新しいトランザクションと何の関連性も持たず、以後のトランザクション コンテキストにその接続を「入れる」ためのセマンティクスも存在しません。 JTS 接続がトランザクション コンテキストに関連付けられていない場合、JTS 接続は自動コミットを true に設定した標準の JDBC 接続と同じように動作し、更新はデータストアに自動的にコミットされます。

いったんトランザクション コンテキスト内にデータベース接続を作成すれば、その接続はトランザクションがコミットまたはロールバックされるまで「予約」状態になります。アプリケーションのパフォーマンスとスループットを維持するには、常にトランザクションを迅速に完了させることによって、データベース接続を解放し、他のクライアント リクエストが使用できるようにする必要があります。 詳細については、トランザクション リソースの保持を参照してください。

注意: アクティブなトランザクション コンテキストには単一のデータベース接続しか関連付けることができません。

コンテナ管理 EJB に対する制限

コンテナ管理によるトランザクションを使用する EJB 内で javax.transaction.UserTransaction メソッドを使用することはできません。

トランザクションのアイソレーション レベル

トランザクションのアイソレーション レベルを設定する方法は、アプリケーションが Bean 管理による境界設定を使用するか、コンテナ管理による境界設定を使用するかによって異なります。以下の節では、これらのシナリオの各々について検討します。

Bean 管理トランザクションのアイソレーション レベルの設定

Bean 管理のトランザクションのアイソレーション レベルは、EJB の Java コードで設定します。 アプリケーションが実行されると、トランザクションが明示的に開始されます。 指定できるアイソレーション レベルはtransaction-isolationで定義されています。

注意: Oracle 専用のアイソレーション レベル値 (TRANSACTION_READ_COMMITTED_FOR_UPDATETRANSACTION_READ_COMMITTED_FOR_UPDATE_NO_WAIT) は、Bean 管理のトランザクションでは設定できません。

サンプル コードについては 図 4-12 を参照してください。

図4-12 トランザクションのアイソレーション レベルの設定のサンプル コード

import javax.transaction.Transaction;
import java.sql.Connection
import weblogic.transaction.TxHelper:
import weblogic.transaction.Transaction;
import weblogic.transaction.TxConstants;
User Transaction tx = (UserTransaction)
ctx.lookup("javax.transaction.UserTransaction");
//ユーザ トランザクションを開始する
	tx.begin();
//トランザクションのアイソレーション レベルを TRANSACTION_READ_COMMITED に設定する
Transaction tx = TxHelper.getTransaction();
tx.setProperty (TxConstants.ISOLATION_LEVEL, new Integer
(Connection.TRANSACTION_READ_COMMITED));
//トランザクションの処理を実行する
	tx.commit();

コンテナ管理トランザクションのアイソレーション レベルの設定

コンテナ管理トランザクションのアイソレーション レベルは、weblogic-ejb-jar.xml デプロイメント ファイルの transaction-isolation 要素の isolation-level サブ要素で設定します。WebLogic Server は、この値を基盤データベースに渡します。トランザクションの動作は、EJB のアイソレーション レベル設定と、基盤となる永続ストレージの同時実行性の制御に依存します。 コンテナ管理トランザクションのアイソレーション レベルの設定に関する詳細については、『WebLogic JTA プログラマーズ ガイド』を参照してください。

TransactionSerializable の制限

多くのデータストアでは、シリアライゼーションに関する問題の検出は、単一ユーザ接続の場合でさえ制限されています。 したがって、transaction-level を EJB に対して TransactionSerializable 設定にした場合でも、同じ行に対してクライアント間で競合が起きると、その EJB クライアントで例外またはロールバックを受け取ることがあります。こうした問題を避けるには、クライアント アプリケーションのコードが SQL 例外を検出および調査して、例外を解決するためにトランザクションをやり直すなどの適切なアクションを取るようにしなければなりません。

WebLogic Server では、Oracle データベースに関する特別な注意で説明しているように、Oracle データ―ベースでこの問題を回避するために設計された特別な isolation-level 設定を用意しています。

その他のデータベース ベンダについては、使用しているデータベースのマニュアルでアイソレーション レベルのサポートに関する詳細を参照してください。

Oracle データベースに関する特別な注意

isolation-level の設定を TransactionSerializable にしたとしても、Oracle ではコミット時までシリアライゼーションの問題が検出されません。返されるエラー メッセージは次のとおりです。

java.sql.SQLException: ORA-08177: can't serialize access for this transaction

WebLogic Server では、これを回避するために特別な isolation-level 設定を提供しています。詳細については、isolation-levelを参照してください。

複数の EJB 間でのトランザクションの分散

WebLogic Server は、複数のデータストアに分散されるトランザクションをサポートしています。このため、単一のデータベース トランザクションを複数のサーバの複数の EJB に分散できます。これらのタイプのトランザクションを明示的にサポートするには、トランザクションを開始し、複数の EJB を呼び出します。また、単一の EJB が、同じトランザクション コンテキスト内で暗黙的に動作する他の EJB を呼び出す場合もあります。以降の節では、これらのシナリオについて説明します。

単一トランザクション コンテキストから複数の EJB を呼び出す

次のコードでは、クライアント アプリケーションは UserTransaction オブジェクトを取得し、それを使ってトランザクションを開始してコミットします。クライアントは、トランザクションのコンテキストの中で 2 つの EJB を呼び出します。 各 EJB のトランザクション属性は、Required に設定されています。

図4-13 トランザクションの開始とコミット

import javax.transaction.*;
...
u = (UserTransaction) jndiContext.lookup("javax.transaction.UserTransaction");
u.begin();
account1.withdraw(100);
account2.deposit(100);
u.commit();
...

上のコードでは、「account1」および「account2」 EJB によって行われる更新は、単一の UserTransaction のコンテキスト内で発生します。EJB は、1 つの論理単位としてコミットまたはロールバックされます。このことは、「account1」と「account2」が同じ WebLogic Server、複数の WebLogic Server、または WebLogic Server クラスタのどれに存在している場合にも当てはまります。

EJB 呼び出しをこのようにラップするための条件は、「account1」と「account2」のどちらもクライアント トランザクションをサポートしなければならないということだけです。 これを満たすには、Bean の trans-attribute 要素を RequiredSupports、または Mandatory に設定します。

複数操作トランザクションをカプセル化する

また、トランザクションをカプセル化する「ラッパー」EJB を使用することもできます。クライアントは、ラッパー EJB を呼び出して銀行振替などのアクションを実行します。ラッパー EJB は、新しいトランザクションを開始し、1 つまたは複数の EJB を呼び出してトランザクションの作業を実行することで、それに応答します。

「ラッパー」EJB は、他の EJB を呼び出す前にトランザクション コンテキストを明示的に取得することもできます。また、EJB の trans-attribute 要素が Required または RequiresNew に設定されている場合、WebLogic Server は新しいトランザクション コンテキストを自動的に作成できます。 trans-attribute 要素は、weblogic-ejb-jar.xml ファイルで設定します。 ラッパー EJB によって呼び出されるすべての EJB は、トランザクション コンテキストをサポートできなければなりません (その trans-attribute 要素が RequiredSupports、または Mandatory に設定されていなければなりません)。

WebLogic Server クラスタ内の複数の EJB 間でトランザクションを分散する

WebLogic Server では、WebLogic Server クラスタ内の EJB に対してはトランザクションのパフォーマンスがさらに向上します。単一のトランザクションが複数の EJB を使用する場合、WebLogic Server は異なるサーバの EJB ではなく、単一の WebLogic Server インスタンスに存在する EJB インスタンスを使おうとします。この方法を使用すると、トランザクションのネットワーク トラフィックを最小限に抑えることができます。

場合によっては、トランザクションはクラスタ内の複数の WebLogic Server インスタンスに存在する EJB を使用します。これは、すべての EJB がすべての WebLogic Server インスタンスにデプロイされていない異種クラスタで起こる場合があります。このような場合、WebLogic Server は複数の直接接続ではなく 1 つの多層接続を使用してデータベースにアクセスします。この方法を使うと、リソースの使用量が減り、トランザクションのパフォーマンスが向上します。

しかし、最高のパフォーマンスを得るには、クラスタを同種にする必要があります。つまり、すべての EJB が使用可能なすべての WebLogic Server インスタンスに存在する必要があります。

 


データベースの挿入サポート

WebLogic Server では、EJB コンテナが新規作成されたBean をどの時点で、どのようにデータベースに挿入するかを管理できます。 weblogic-cmp-rdbms-jar.xml ファイルのdelay-database-insert-until デプロイメント記述子要素を設定することによって各自の希望を指定します。次のものから選択できます。

delay-database-insert-until 要素には、以下の値を指定できます。

<delay-database-insert-until>ejbPostCreate</delay-database-insert-until> --> 

Delay-Database-Insert-Until

デフォルトでは、データベースへの挿入はクライアントが ejbPostCreate メソッドを呼び出した後に行われます。 weblogic-cmp-rdbms-jar.xml ファイルの delay-database-insert-until 要素に ejbCreate または ejbPostCreate を指定した場合、EJB コンテナは新規 Bean の挿入を遅延させます。このどちらかのオプションを指定することによって、EJB コンテナが RDBMS CMP を使用する新しい Bean をいつデータベースに挿入するかを正確に指定します。

cmr-field が null 値を許可しない foreign-key column にマップされている場合、EJB コンテナがデータベースの挿入を ejbPostCreate の後まで遅らせるように指定する必要があります。 この場合、 cmr-fieldejbPostCreate で null でない値に設定してから Bean をデータベースに挿入します。

注意: Bean の主キーが不明な段階で、cmr-fieldsejbCreate メソッド呼び出しの中で設定することはできません。

BEA では、ejbPostCreate メソッドが Bean の永続フィールドを変更した場合には、データベースの挿入を ejbPostCreate の後に遅らせるよう指定することを推奨しています。これにより、不要な保存操作を行わずに済むので、パフォーマンスが向上します。

最大限の柔軟性を実現するため、関連 Bean を ejbPostCreate メソッドで作成することは避けてください。こうしたインスタンスを追加作成すると、データベースの制約によって関連 Bean が未作成の Bean を参照できない場合、データベースの挿入を遅らせることができなくなる可能性があります。

注意: 1 対 1 の関係では、親 Bean の主キーが子 Bean の CMR フィールドに埋め込まれている場合、EJB コンテナが Bean を作成するときに、パフォーマンス上の理由からその親 Bean に子があるかどうかが確認されません。 duplicationKeyException データベース例外を防止するには、データベースの子テーブルで外部キー制約を設定する必要があります。

一括挿入

一括挿入のサポートにより、コンテナ管理による永続性(CMP) Bean の作成における効率が向上します。EJB コンテナが 1 つの SQL 文で CMP Bean での複数回のデータベース挿入を実行できるようになるためです。この機能により、コンテナは何度もデータベースを挿入しなくて済むようになります。

weblogic-cmp-rdbms-jar.xml ファイルの delay-database-insert-until 要素に commit オプションを指定した場合、EJB コンテナは一括データベース挿入を実行します。

一括挿入更新を使用する場合、トランザクションの開始からコミットまでの間に一括挿入だけが挿入に適用されるように、トランザクションの境界を設定しなければなりません。

注意: 一括挿入は、addBatch()executeBatch() メソッドをサポートしているドライバのみに機能します。たとえば、Oracle Thin ドライバはこれらのメソッドをサポートしていますが、 WebLogic Oracle JDBC ドライバはサポートしていません。

一括挿入の使用に際しては、次の 2 つの制限があります。

1 回の一括挿入で作成するエントリの総数が、weblogic-ejb-jar.xml ファイルで指定したmax-beans-in-cache の設定値を超えることはできません。 この要素の詳細については、max-beans-in-cacheを参照してください。

weblogic-cmp-rdbms-jar.xml ファイルの dbms-column-type 要素で OracleBlobOracleClob を設定した場合、一括挿入は自動的に無効になります。 Blob または Clob カラムがデータベース テーブルに含まれている状況では、時間短縮があまりできないからです。この場合、デフォルトでは WebLogic Server は Bean ごとに挿入を実行します。

 


リソース ファクトリ

以降の節では、EJB コンテナによるリソース サービスのサポートについての情報を示します。WebLogic Server では、EJB は JDBC ドライバを直接インスタンス化することによって JDBC 接続プールにアクセスできます。しかし、その代わりに、JDBC データソース リソースをリソース ファクトリとして WebLogic Server JNDI ツリーにバインドすることをお勧めします。

リソース ファクトリを使用すると、EJB はEJB デプロイメント記述子内のリソース ファクトリ参照を稼働中の WebLogic Server で使用可能なリソース ファクトリにマップできます。リソース ファクトリ参照は使用するリソース ファクトリ タイプを定義しなければなりませんが、リソースの実際の名前は、Bean がデプロイされるまで指定されません。

以降の節では、JDBC データソース および URL リソースを WebLogic Server の JDNI 名にマップする方法について説明します。

注意: WebLogic Server は、JMS 接続ファクトリもサポートしています。

JDBC データソース ファクトリの設定

次の手順に従って、javax.sql.DataSource リソース ファクトリを WebLogic Server 内の JNDI 名にバインドします。必要に応じて、トランザクション対応か非対応の JDBC データソースを設定できます。

トランザクション非対応のデータソースの場合、JDBC 接続は自動コミットモードで動作し、コンテナ管理トランザクションの一部にはならず、挿入操作や更新操作のつど、データベースに即座にコミットします。

トランザクション対応のデータソースの場合、あるメソッド上の複数回の挿入および更新操作を 1 つのコンテナ管理トランザクションとして送信することができ、1 つの論理単位としてコミットまたはロールバックされます。

注意: コンテナ管理による永続性を使用するエンティティ Bean では、データの一貫性を保つため、トランザクション非対応のデータソースではなくトランザクション対応のデータソースを必ず使用します。

JDBC データソース ファクトリを作成するには、以下の手順に従います。

  1. Administration Console で JDBC 接続プールを設定します。 詳細については、『管理者ガイド』の「JDBC 接続の管理」を参照してください。

  2. WebLogic Server を起動します。

  3. WebLogic Server Administration Console を起動します。

  4. Administration Console の左ペインで、[サービス] ノードをクリックして JDBC を展開します。

  5. [JDBC データ ソース ファクトリ] を選択し、右ペインで [新しい JDBCDataSource のコンフィグレーション] オプションをクリックします。

  6. [名前]、[ユーザ名]、[URL]、[ドライバ クラス名]、[ファクトリ名] 属性フィールドに値を入力します。

  7. [プロパティ] 属性フィールドにすべての接続プロパティを入力します。

    1. トランザクション非対応の JDBC データソースの場合は、次のとおり入力します。
      weblogic.jdbc.DataSource.jndi_name=pool_name

    ここで jndi_name は、データソースにバインドする完全な WebLogic Server JNDI 名、pool_name は、手順 1 で作成した WebLogic Server 接続プールの名前です。

    1. トランザクション対応の JDBC データベースの場合は、Administration Console の左ペインで [トランザクション データソース] を選択し、右ペインで [新しいJDBCTxDataSource のコンフィグレーション] をクリックし、次のように入力します。
      weblogic.jdbc.TXDataSource.jndi_name=pool_name

    ここで jndi_name はトランザクション対応データソースにバインドする完全な WebLogic Server JNDI 名、pool_name は手順 1 で作成した WebLogic Server 接続プールの名前です。

    トランザクション データ ソースと非トランザクション データ ソースの詳細については、「JDBC データ ソースのコンフィグレーション」を参照してください。

  8. [作成] をクリックしてJDBC データ ソース ファクトリを作成します。左ペインの JDBC データソース ノードの下に新しいデータソース ファクトリが追加されます。

  9. [適用] をクリックして変更を保存します。

  10. 次のいずれかの方法で、データソースの JNDI 名を EJB のローカル JNDI 環境にバインドします。

URL 接続ファクトリの設定

WebLogic Server で URL 接続ファクトリを設定するには、次の手順で URL 文字列を JNDI 名にバインドします。

  1. 使用している WebLogic Server のインスタンス用の config.xml ファイルをテキスト エディタで開き、以下の config.xml 要素の URLResource 属性を設定します。

  2. 次の構文に従って、WebServer 要素の URLResource 属性を設定します。
    <WebServer URLResource="weblogic.httpd.url.testURL=http:// localhost:7701/testfile.txt” DefaultWebApp=”default-tests”/>

  3. 仮想ホストが必要な場合は、次の構文に従って VirtualHost 要素の URLResource 属性を設定します。
    <VirtualHostName=guestserver" targets="myserver,test_web_server "URLResource="weblogic.httpd.url.testURL=http:// localhost:7701/testfile.txt” VirtualHostNames=”guest.com”/>

  4. 変更を config.xml に保存し、WebLogic Server を再起動します。

 

Back to Top Previous Next