接続ハンドル

接続ハンドルは、物理接続を表現するものです。 WebSphere® Application Server でリレーショナル・データベースなどのバックエンド・リソースを使用するには、そのリソースへの接続を取得する必要があります。 getConnection() メソッドを呼び出すと、戻される接続ハンドルを受け取ります。 このハンドルは物理接続ではありません。 物理接続は接続マネージャーにより管理されます。

接続ハンドルの使用方法とその動作に影響を与える重要な 2 つの構成があります。1 番目は res-sharing-scope であり、 これは、データ・ソースまたは接続ファクトリーの検索に使用される resource-reference によって定義されます。 このプロパティーは、この接続が共有可能であるかどうかを接続マネージャーに知らせます。

接続ハンドルの動作に影響を与える 2 つ目の要素は、使用パターンです。 基本的に 2 つの使用パターンがあります。 1 つ目は取得/使用/クローズ・パターンと呼ばれます。 このパターンは、単一のメソッド内で、 しかも同じデータ・ソースまたは接続ファクトリーから接続を取得する可能性がある別のメソッドを呼び出さずに、 使用されます。 このパターンを使用するアプリケーションは、以下のことを行います。
  1. 接続を取得する
  2. 作業を実行する
  3. コミットする (必要に応じて)
  4. 接続を閉じる
2 番目の使用パターンは、キャッシュされたハンドル・パターンと呼ばれます。 これは、アプリケーションが以下のことを実行する場合に使用します。
  1. 接続を取得する
  2. グローバル・トランザクションを開始する
  3. この接続で作業を実行する
  4. グローバル・トランザクションをコミットする
  5. この接続で作業を再実行する
キャッシュされたハンドルは、 トランザクションおよびメソッドの境界を越えて、アプリケーションによって保持される接続ハンドルです。 キャッシュされたハンドルを使用する場合は、以下の考慮事項に留意してください。
  • キャッシュされたハンドルをサポートするには、上記の境界での接続ハンドル管理を若干追加する必要がありますが、 これにより、パフォーマンスに影響が生じる場合があります。 例えば、JDBC アプリケーションでは、Statements、PreparedStatements、 および ResultSets はトランザクションの終了後、暗黙的に閉じられますが、接続は有効なままです。
  • 共有可能接続については、 トランザクション境界を越えて接続をキャッシュしないようにしてください。 get/use/close のパターンのほうが適切です。
  • サーブレット・メソッド全体にわたる接続ハンドルのキャッシングは、JDBC と Java™ Message Service (JMS) のリソースに限定されます。顧客情報管理システム (CICS®) や IMS™ オブジェクトなど、その他の非リレーショナル・リソースでは、現在、その接続ハンドルをサーブレットにキャッシュすることはできません。接続ハンドルは、各メソッド呼び出し内で取得、使用、およびクローズする必要があります。 (マルチスレッド・サーブレットでは接続ハンドルのキャッシュを行うことができないので、 この制限は単一スレッド・サーブレットにのみ適用されます。)
  • キャッシュ接続ハンドルは、データ・アクセス・クライアントの 1 つのインスタンスから、 別のクライアント・インスタンスへ受け渡すことができません。クライアント・インスタンス間で転送を行うと、1 つのインスタンスが、別のインスタンスが参照する接続ハンドルを使用するという、問題のある偶然性が発生します。 この関係によって問題が発生する可能性があるのは、 接続ハンドル管理コードが各クライアント・インスタンスに対して 個別にタスクを処理するためです。したがって、接続ハンドルの転送により、ランタイム・シナリオで例外が発生するという結果になります。以下に例を示します。
    1. 転送済みハンドルを受け取るクライアント・インスタンスのアプリケーション・コードは、 ハンドルを閉じます。
    2. 元の参照をハンドルに保存するクライアント・インスタンスが、それを再利用しようとすると、 アプリケーション・サーバーは例外を発行します。

次のコード・セグメントはキャッシュ接続パターンを示しています。

Connection conn = ds.getConnection();
ut.begin();
conn.prepareStatement("....."); // Connection runs in global transaction mode
...
ut.commit();
conn.prepareStatement("....."); // Connection still valid but runs in autoCommit(True);
...

共有不可能接続

以降のセクションで説明しているように、 共有不可能の res-sharing-scope で検索された接続ハンドルにはいくつかの特性があります。
  • 非共有接続の利点としては、以下のことが考えられます。
    • アプリケーションは、物理接続 (管理対象接続) による直接リンクを常に保持します。
    • この接続では、接続ハンドルと管理対象接続は、常に 1 対 1 の関係になっています。
    • ほとんどの場合、アプリケーションにより閉じられるまで、接続は閉じません。
    • 複数のトランザクション間で、 キャッシュされた非共有接続ハンドルを使用することができます。
    • キャッシュされたハンドル状態では、接続においてパフォーマンスの利点を得ることがあります。 非共有接続では、トランザクションの終了時に、 接続ハンドルを管理対象接続から外すというオーバーヘッドが発生しないので、 キャッシュされた非共有接続を使用するほうが、オーバーヘッドは少なくなります。
  • 非共有接続の欠点としては、以下のことが考えられます。
    • 接続リソースの使用方法が非効率的です。 例えば、単一トランザクション内で、 同じデータ・ソースまたは接続ファクトリー (同じ resource-ref) を使用して、 (同じプロパティーを持つ) 複数の接続を取得する場合、 共有不可能接続を使用していると、複数の物理接続を使用することになります。
    • 無駄な接続。 接続ハンドルを、必要以上に長く開いた状態 (すなわちアプリケーションが close() メソッドを呼び出していない 状態) にしておかないことが重要です。 共有不可能接続が開いている間は、アプリケーションが現在その接続を使用していない場合でも、他のいずれのコンポーネントに対しても物理接続を使用できません。共有可能接続とは異なり、共有不可能接続は、トランザクションまたはサーブレット呼び出しの終了時に閉じられません。
    • デッドロックに関する考慮事項。コンポーネントがトランザクション内でデータベースと対話する方法によっては、非共有接続を使用することにより、データベース内でデッドロックが起こる可能性があります。 例えば、トランザクション内で、 コンポーネント A がデータ・ソース X に対する接続を取得して、 表 1 を更新してから、 コンポーネント B を呼び出します。 コンポーネント B はデータ・ソース X に対する別の接続を取得して、 表 1 の更新/読み取りを行います (すなわち、そのコンポーネント B がコンポーネント A と同じ行にある場合は デッドロック状況はさらに悪くなります)。 特定のデータベース、そのロック方式、 およびトランザクションの分離レベルによって決まる状況によっては、 デッドロックが発生する可能性があります。

      同じシナリオでも、共有接続を使用した場合、デッドロックは発生しません。この場合は、すべての作業が同じ接続上で行われたためです。 共有接続を使用するコードを作成するときに、複数の作業項目の呼び出しを同じ接続上 (できれば同じトランザクション内で) で実行する方針をとることが重要です。共有不可能接続を使用することにした場合は、 接続ファクトリーまたはデータ・ソースに maximum connections プロパティーを正しく設定する必要があります。 最大接続値を超え、接続待ちのタイムアウトを超過する前に共有不可能接続が閉じられないと、接続要求待ちに対して例外が発生する場合があります。

共有可能接続

以降のセクションで説明しているように、共有可能の res-sharing-scope で検索された接続ハンドルにはいくつかの特性があります。
  • 共有接続の利点としては、以下のことが考えられます。
    • 接続を共有するインスタンス内で、アプリケーション・コンポーネントは、ハンドルの検索方法や使用されている接続プロパティーに応じて、1 つ以上の接続ハンドルにより管理対象の接続を共有することができます。
    • リソースをより効率的に使用できます。 共有可能接続は、その共有境界の外側では無効です。 このため、共有境界 (トランザクションなど) の限界では、接続ハンドルは、共有境界内で使用していた管理対象接続と関連付けられなくなります (キャッシュされたハンドル・パターンを使用している場合のみ)。 管理対象接続は、フリー接続プールに戻され再利用されます。 接続リソースは、現在の共有有効範囲の限界よりも長くは保持されません。

      キャッシュされたハンドル・パターンを使用すると、そのハンドルが新しい共有有効範囲内で次に使用されるときに、現在の共有有効範囲に該当する管理対象接続にハンドルが再び関連付けられ、そのハンドルの最初の検索に使用されたものと同じプロパティーをハンドルが持つことが、アプリケーション・サーバー・ランタイムによって保証されます。 共有可能接続でプロパティーを変更することは適切ではないことを覚えておいてください。 プロパティーを変更すると、 同じ接続を共有する他のコンポーネントが予期しない動作をする可能性があります。 さらに、キャッシュされたハンドルを使用する場合、 変更したプロパティーの値は、共有有効範囲間では記憶されません。

  • 共有接続の欠点としては、以下のことが考えられます。
    • 単一コンポーネント (エンタープライズ Bean とそれに関連した Java オブジェクトなど) 内での共有は、 常にサポートされるわけではありません。 現行の仕様では、 リソース・アダプターには、 一度に 1 つの接続ハンドルだけをアクティブにできるという選択肢が許可されています。
      リソース・アダプターがこのオプションの実装を選択すると、 以下のシナリオでは、無効なハンドル例外が発生します。 共有可能接続を使用するコンポーネントは、接続を取得して、それを使用します。 コンポーネントは、接続を閉じずにユーティリティー・クラス (Java オブジェクト) を呼び出し、そのクラスが同じ管理対象接続に対する接続ハンドルを取得して、その接続ハンドルを使用します。 リソース・アダプターはアクティブ・ハンドルを 1 つしかサポートしないので、 最初の接続ハンドルは無効になります。 ユーティリティー・オブジェクトが、そのハンドルを閉じずに戻される場合、最初のハンドルは無効であり、それを使用しようとすると例外が発生します。
      注: この例外は、 ユーティリティー・オブジェクト (Java オブジェクト) を呼び出す場合にのみ発生します。

      すべてのリソース・アダプターにこの制限が適用されるわけではなく、特定の実装方法においてのみ適用されます。 WebSphere リレーショナル・リソース・アダプター (RRA) にこの制限は適用されません。 RRA を介して使用されるデータ・ソースにはいずれもこの制限は適用されません。 この制限があるリソース・アダプターが見つかった場合は、 管理対象接続に対するアクセスをシリアライズすることで、 これに対処することができます。 別の接続ハンドルを取得する前に必ず接続ハンドルを閉じる場合 (または別のハンドルを取得するコードを呼び出す前にハンドルを閉じる)、メソッドから戻る前であれば、2 種類のコードによって同じ管理対象接続を共有することができます。 ただ、両方のイベントに対して、同時にこの接続を使用することはできません。

    • グローバル・トランザクションで共有可能な JDBC ベースの接続で「分離レベル」を変更しようとすると、例外が発生します。 異なるトランザクション分離レベルで接続を取得する正しい方法は、IBM® 拡張リソース参照を構成することです。
    • 通常、アプリケーションで共有可能な接続の接続ハンドルを閉じるようにはサポートされていないので、 エラーになります。 ただし、この制限は、リレーショナル・リソース・アダプターを使用することで回避できます。

遅延接続関連の最適化

Java Platform, Enterprise Edition (Java EE) Connector (J2C) 接続マネージャーに スマート・ハンドル・サポートが実装されました。このテクノロジーにより、アプリケーションへの接続ハンドルの割り振りにおいて、その接続ハンドルに関連した管理対象の接続を他のアプリケーションでも使用できるようになります (接続がオリジナルのアプリケーションによって使用されていないことが前提)。この概念は、Java EE コネクター・アーキテクチャー (JCA) 1.5 仕様に組み込まれています。(JCA 1.5 仕様文書の『Lazy Connection Association Optimization』のセクションに記載。)スマート・ハンドルのサポートにより、ConnectionManager オブジェクト上のメソッド、LazyAssociatableConnectionManager() メソッド、および新しいマーカー・インターフェースの DissociatableManagedConnection クラスの使用が導入されます。環境内でこの機能を使用するには、リソース・アダプターのプロバイダーを構成する必要があります。(RRA の場合、WebSphere Application Server そのものがプロバイダーとなります。) 以下のコードの断片に、スマート・ハンドル・サポートを組み込む方法を示します。
package javax.resource.spi;
import javax.resource.ResourceException;

interface LazyAssociatableConnectionManager { // application server
    void associateConnection(
        Object connection, ManagedConnectionFactory mcf,
        ConnectionRequestInfo info) throws ResourceException;
}

interface DissociatableManagedConnection { // resource adapter
    void dissociateConnections() throws ResourceException;
}

DissociatableManagedConnection インターフェースは、Connection オブジェクトにもう 1 つの状態である非アクティブを導入します。これで、Connection は、アクティブ、クローズ、および非アクティブの状態を持つようになりました。接続オブジェクトは、対応する ManagedConnection オブジェクトがクリーンアップされると、非アクティブ状態になります。接続は、アプリケーション・コンポーネントが接続の再使用を試みるまで、非アクティブとなります。リソース・アダプターは接続マネージャーを呼び戻して、接続をアクティブな ManagedConnection オブジェクトに再度関連付けます。


トピックのタイプを示すアイコン 概念トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=cdat_cconpconh
ファイル名:cdat_cconpconh.html