データベースに対して処理を実行するには、定義したJDBCリソースを以下の例のようにJNDIのメソッド(lookupなど)を使用して取得し、データベースへの処理要求を実行します。
データベースの処理要求は、JDBC APIを使用して実行します。JDBC APIの詳細は、JDBC API規約を参照してください。
例
InitialContext ctx = new InitialContext(); javax.sql.DataSource ds = ctx.lookup("jdbc/MyBase"); Connection con = ds.getConnection(); // データベース処理を実行 con.close();
JDBCの標準APIだけサポートします。各JDBCドライバ固有のメソッド(OracleConnection固有のメソッドなど)は使用できないため、標準のAPIを使用してください。固有のメソッドを実行するためにオブジェクトをJDBCドライバ固有のクラスにキャストしようとした場合には、java.lang.ClassCastExceptionが発生します。
共有接続
同一のJDBCリソースに対して接続を使用する場合、同一トランザクション範囲内で接続は共有されます。例えばアプリケーションAでトランザクションの開始とJDBCリソースに対する接続の獲得を行い、同一のトランザクション範囲内でアプリケーションBが同一のJDBCリソースに対して同一の認証情報(ユーザID/パスワード)で接続を獲得した場合、Aがトランザクションを完了させるまで接続は共有されます。
Java EEコンポーネントが接続の共有を許可した場合だけ、JDBCリソースから取得する接続は共有されます。リソース参照項目のres-sharing-scope要素にShareableを定義した場合、接続は共有されます。接続を共有しない場合には、Unshareableを定義します。
非トランザクション接続
トランザクション管理を行わないでデータベースにアクセスする場合の指定方法は以下です。一般的にgetConnectionを実行することで、トランザクションコンテキストに接続が参加します。しかし、トランザクション管理されない接続を使用することで、トランザクションコンテキストへの接続の参加・離脱が実行されないため、性能オーバーヘッドが軽減されるメリットがあります。
しかし、トランザクション管理を行わない接続を使用する場合は注意が必要です。例えば、トランザクション管理されない接続を使用してデータベースにアクセスした場合、別の業務でデータベースのデータを変更中にデータを参照した場合には、変更前のデータが参照されます。これは、進行中のトランザクションがコミットしていないためです。別の例では、トランザクション管理されない接続がデータベースのデータを変更し、同時に実行されているトランザクションがロールバックされた場合、トランザクション管理されない接続による変更はロールバックされません。
データベースに対する一連の処理で整合性を保つためには、トランザクション管理する必要があります。以下の方法で設定します。
asadminコマンドのcreate-jdbc-connection-poolサブコマンドでnontransactionalconnectionsオプションを有効にします。作成後にsetサブコマンドで更新することもできます。
JDBCリソースを作成する際のJNDI名の最後に「__nontx」を指定します。このJDBCリソースから取得した接続は、強制的にトランザクション管理されません。
注意
非トランザクション接続を使用する場合、またはJTAトランザクションを開始せずにデータベースにアクセスする場合の注意事項を以下に記載します。
接続の自動コミットモードは有効で動作します。
接続の自動コミットモードを無効にした場合、接続をクローズする前にコミット、またはロールバックを実行してください。コミットやロールバックを実行せずに接続をクローズした場合、データベース操作が反映されない、または想定外のタイミングでデータベース操作が反映されるなどの異常な動作をする場合があります。
トランザクション遮断と遮断レベル
データベースは、トランザクションのロックレベルをチューニングするため、トランザクション遮断レベルをサポートしています。すべてのデータベースがすべてのトランザクション遮断レベルをサポートしているわけではありません。各データベースのトランザクション遮断レベルのサポート状況については、各データベースのマニュアルを参照してください。
トランザクション遮断レベル | 説明 | ||
---|---|---|---|
ダーティリード | ノンリピータブルリード | ファントムインサート | |
TRANSACTION_READ_UNCOMMITTED | 発生 | 発生 | 発生 |
TRANSACTION_READ_COMMITTED | 抑制 | 発生 | 発生 |
TRANSACTION_REPEATABLE_READ | 抑制 | 抑制 | 発生 |
TRANSACTION_SERIALIZABLE | 抑制 | 抑制 | 抑制 |
ダーティリード
他のトランザクションがデータの変更を取り消したにもかかわらず、取り消し前にそのデータを読み出してしまうこと。
ノンリピータブルリード
あるトランザクションにおいて、同じ行を2回読み込んだ時に、1回目と2回目の読み込みの間に、他のトランザクションが行の値を変更したため、1回目と2回目で読み込んだデータの値が異なってしまうこと。
ファントムインサート
あるトランザクションにおいて、WHERE句などによる同じ条件により行を読み込んだ時に、その途中に他のトランザクションがその条件に影響を与える行を挿入したために、先に読み込んだ行と後に読み込んだ行が異なってしまうこと。
トランザクション遮断
接続プールにトランザクション遮断レベルを設定する方法を説明します。指定しない場合、接続にはJDBCドライバによって設定されるデフォルトのトランザクション遮断レベルが適用されます。以下の方法で設定します。
asadminコマンドのcreate-jdbc-connection-poolサブコマンドでisolationlevelオプションにトランザクション遮断レベルを指定します。作成後にsetサブコマンドで更新することもできます。
遮断レベル
接続プールから取得されるすべての接続が同じ遮断レベルになります。上記のトランザクション遮断を指定した場合にだけ適用されます。例えば、最後の使用時に接続のsetTransactionIsolation()メソッドを呼び出してトランザクション遮断レベルをクライアント側で明示的に変更した場合、一度プールに戻された接続を再取得すると、このメカニズムによって指定のトランザクション遮断レベルに戻されます。以下の方法で設定します。
asadminコマンドのcreate-jdbc-connection-poolサブコマンドでisisolationguaranteedオプションを有効にします。作成後にsetサブコマンドで更新することもできます。
トランザクション開始後の接続のみ参加
本機能が有効なJDBCリソースの場合、JTAトランザクション開始後にオープンした接続だけトランザクションに参加します。本機能が無効なJDBCリソースの場合、JTAトランザクション範囲外でオープンした接続は、JTAトランザクション開始時にトランザクションに参加します(JTAトランザクションの対象となります)。
しかし、本機能を使用すると処理が煩雑になるため、JTAトランザクションに接続を参加させない場合には、非トランザクション接続を使用することをお勧めします。
以下の方法で「トランザクション開始後の接続のみ参加」の接続を取得できます。
asadminコマンドのcreate-jdbc-connection-poolサブコマンドでallownoncomponentcallersオプションを有効にします。作成後にsetサブコマンドで更新することもできます。
JDBCリソースの作成にあわせてネーミングサービスに自動的に登録される、最後に「__pm」が付加されたJNDI名をクライアントから参照します。