6.2. JDBC データソースの概要
JDBC 1.4 標準では、java.sql.Connection オブジェクトの ファクトリー として機能する javax.sql.DataSource インターフェイスが導入されました。通常、このようなデータソースは JNDI レジストリーにバインドされ、サーブレットや EJB などの JavaEE コンポーネント内に配置または挿入されていました。重要な側面は、これらのデータソースが アプリケーションサーバー 内で 設定 され、デプロイされたアプリケーションで名前で 参照 されていることです。
以下の 接続 オブジェクトには独自の データソース があります。
| データソース | 接続 |
|---|---|
|
|
|
|
|
|
|
|
|
上記の各 データソース で最も重要な相違点は以下のとおりです。
最も重要なのは、
javax.sql.DataSourceは、java.sql.Connectionインスタンスを取得するための ファクトリーのようなオブジェクトである点です。ほとんどのjavax.sql.DataSource実装が通常接続プーリングを実行することが事実であり、イメージを変更すべきではありません。これは、アプリケーションコードで使用する必要がある唯一のインターフェイスです。実装しているのはどれかは重要ではありません。- 直接 JDBC アクセス
-
JPA 永続ユニット設定 (
<jta-data-source>または<non-jta-data-source>) - Apache Camel や Spring Framework などの一般的なライブラリー
最も重要なのは、
javax.sql.ConnectionPoolDataSourceは汎用 (データベース固有でない) 接続プール/データソースとデータベース固有のデータソースとの間の ブリッジ であることです。SPI インターフェイスとして処理できます。通常、アプリケーションコードは、JNDI から取得され、アプリケーションサーバーによって実装される汎用javax.sql.DataSourceオブジェクトに対応します (おそらくcommons-dbcp2などのライブラリーを使用します)。一方、アプリケーションコードはjavax.sql.ConnectionPoolDataSourceと直接インターフェイスしません。これは、アプリケーションサーバーとデータベース固有のドライバーの間で使用されます。以下のシーケンス図は、これを示しています。
javax.sql.XADataSourceは、javax.sql.XAConnectionとjavax.transaction.xa.XAResourceを取得する方法です。javax.sql.ConnectionPoolDataSourceと同じで、これはアプリケーションサーバーとデータベース固有のドライバーとの間で使用されます。これは、今回は JTA トランザクションマネージャーなど、異なるアクターが含まれる図を若干変更しています。
上記の 2 つの図に示すように、アプリケーションサーバーと対話できます。これは一般的なエンティティーで、 javax.sql.DataSource および javax.transaction.UserTransaction インスタンスを設定できます。このようなインスタンスには、JNDI を使用するか、CDI や他の依存関係メカニズムを使用して注入することでアクセスできます。
重要な点は、アプリケーションが XA トランザクションや接続プーリングを使用する場合でも、アプリケーションは他の 2 つの JDBC データソースインターフェイスではなく、javax.sql.DataSource と対話することです。
6.2.1. データベース固有のデータソースおよび汎用データソース リンクのコピーリンクがクリップボードにコピーされました!
JDBC データソースの実装は 2 つのカテゴリーに分類されます。
以下のような汎用の
javax.sql.DataSource実装:- Apache Commons DBCP(2)
- Apache Tomcat JDBC(DBCP ベース)
-
javax.sql.DataSource、javax.sql.XADataSource、およびjavax.sql.ConnectionPoolDataSourceのデータベース固有の実装
汎用 javax.sql.DataSource 実装によって独自のデータベース固有の接続を作成できないことが紛らわしい可能性があります。汎用 データソースが java.sql.Driver.connect() または java.sql.DriverManager.getConnection() を使用できたとしても、データベース固有の javax.sql.DataSource 実装でこの 汎用 データソースを設定するのが通常、適切またはクリーンです。
汎用 データソースが JTA と対話する場合は、javax.sql.XADataSource のデータベース固有の実装で設定する 必要 があります。
イメージを閉じるには、通常、汎用 データソースは、接続プーリングを実行するために javax.sql.ConnectionPoolDataSource のデータベース固有の実装を必要としません。既存のプールは通常、標準の JDBC インターフェイス (javax.sql.ConnectionPoolDataSource および javax.sql.PooledConnection) なしでプーリングを処理し、代わりに独自のカスタム実装を使用します。
6.2.2. 一部の汎用データソース リンクのコピーリンクがクリップボードにコピーされました!
サンプルのよく知られた汎用データソースである ApacheCommonsDBCP(2) を見ていきます。
javax.sql.XADataSource 実装
DBCP2 には、javax.sql.XADataSource の実装は含まれていないことが予想されます。
javax.sql.ConnectionPoolDataSource implementations
DBCP2 には javax.sql.ConnectionPoolDataSource: org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS の実装が含まれます。java.sql.DriverManager.getConnection() を呼び出して javax.sql.PooledConnection オブジェクトを作成します。このプールを直接使用することはできず、以下のドライバーの アダプター として扱う必要があります。
-
独自の
javax.sql.ConnectionPoolDataSource実装は指定しないでください。 - 接続プールに関する JDBC の推奨事項 に応じて使用する必要があります。
上記のシーケンス図に示すように、ドライバーは javax.sql.ConnectionPoolDataSource を直接提供するか、org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS アダプター の助けを借りて提供します。一方、DBCP2 は、以下のいずれかで アプリケーションサーバー コントラクトを以下のいずれかで実装します。
-
org.apache.commons.dbcp2.datasources.PerUserPoolDataSource -
org.apache.commons.dbcp2.datasources.SharedPoolDataSource
これらのプールは、設定段階で javax.sql.ConnectionPoolDataSource のインスタンスを取ります。
これは DBCP2 の最も重要で興味深い部分です。
javax.sql.DataSource implementations
接続プール機能を実装するには、JDBC の推奨事項 に従って、javax.sql.ConnectionPoolDataSource javax.sql.PooledConnection SPI を使用する必要はありません。
以下は、DBCP2 の 通常 のデータソースの一覧です。
-
org.apache.commons.dbcp2.BasicDataSource -
org.apache.commons.dbcp2.managed.BasicManagedDataSource -
org.apache.commons.dbcp2.PoolingDataSource -
org.apache.commons.dbcp2.managed.ManagedDataSource
2 つの 軸 があります。
基本 vs プーリング
この軸は、プーリング設定の要素を決定します。
いずれの種類のデータソースも、java.sql.Connection オブジェクトの プーリング を実行します。唯一 の違いは、以下の点です。
-
基本的な データソースは、
org.apache.commons.pool2.impl.GenericObjectPoolの内部インスタンスを設定するために使用されるmaxTotalまたはminIdleなどの Bean プロパティーを使用して設定されます。 -
プーリング データソースは、外部作成/設定された
org.apache.commons.pool2.ObjectPoolで設定されます。
managed vs non-managed
この軸は、接続作成の要素と JTA の動作を決定します。
管理対象外の基本的な データソースは、
java.sql.Driver.connect()を内部で使用することで、java.sql.Connectionインスタンスを作成します。管理対象外のプーリング データソースは、渡された
org.apache.commons.pool2.ObjectPoolオブジェクトを使用してjava.sql.Connectionインスタンスを作成します。管理対象のプーリングデータソースは、
org.apache.commons.dbcp2.managed.ManagedConnectionオブジェクト内でjava.sql.Connectionインスタンスをラップし、JTA コンテキストで必要に応じてjavax.transaction.Transaction.enlistResource()が呼び出されるようにします。ただし、ラップされる実際の接続は、プールが設定されたorg.apache.commons.pool2.ObjectPoolオブジェクトから取得されます。managed basic データソースは、専用の
org.apache.commons.pool2.ObjectPoolの設定を解放します。代わりに、既存の実際のデータベース固有のjavax.sql.XADataSourceオブジェクトを設定すれば十分です。Bean プロパティーは、org.apache.commons.pool2.impl.GenericObjectPoolの内部インスタンスを作成するために使用されます。これは、管理対象プーリングのデータソースの内部インスタンス (org.apache.commons.dbcp2.managed.ManagedDataSource) に渡されます。
DBCP2 を実行できないのは XA トランザクションの回復 です。DBCP2 はアクティブな JTA トランザクションで XAResources を正しく登録しますが、リカバリーは実行されません。これは個別に行う必要があり、設定は、通常選択されたトランザクションマネージャーの実装 (Narayana など) に固有のものです。
6.2.3. 使用するパターン リンクのコピーリンクがクリップボードにコピーされました!
推奨のパターンは以下のとおりです。
-
接続/XA 接続を作成できるデータベース固有の設定 (URL、クレデンシャルなど) で、データベース固有 の
javax.sql.DataSourceまたはjavax.sql.XADataSourceインスタンスを作成または取得します。 -
データベース固有でない設定 (接続プーリング、トランザクションマネージャーなど) でデータベース固有でない
javax.sql.DataSourceインスタンス (上記のデータベース固有のデータソースで内部的設定された) を作成および取得します。 -
javax.sql.DataSourceを使用してjava.sql.Connectionのインスタンスを取得し、JDBC 操作を実行します。
以下は 正規 の例です。
Fuse 環境では設定オプションが多くなり、DBCP2 を使用する必要はありません。