2.3.8 バッチアプリケーションの実装(リソースに接続する場合)
ここでは,リソースに接続するバッチアプリケーションの作成方法について説明します。新規にバッチアプリケーションを作成する場合と,既存のバッチアプリケーションから移行する場合について説明します。
(1) 新規にバッチアプリケーションを作成する場合
新規にバッチアプリケーションを作成する場合,リソースへの接続にはDB Connectorを使用することをお勧めします。DB Connectorとは,アプリケーションサーバで提供するデータベースに接続するためのリソースアダプタです。DB Connectorを使用したリソースに接続する方法を次に示します。
-
バッチサーバでDB Connectorを設定します。
ユーザ指定名前空間機能を使用して,DB Connectorのオブジェクトに別名を付けてJNDI名前空間に登録します。バッチアプリケーションからデータベースに接続するときには,必ずユーザ指定名前空間機能を使用してください。
別名は,DB Connectorをバッチサーバにデプロイしたあと,Connector属性ファイルで設定します。次の設定例のように,Connector属性ファイルの<resource-external-property>タグに<optional-name>タグを追加して別名を設定します。
設定例
<connector-runtime> : <resource-external-property> <optional-name>DB Connectorの別名</optional-name> </resource-external-property> </connector-runtime>
DB Connectorの別名の付け方については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「2.6 Enterprise BeanまたはJ2EEリソースへの別名付与(ユーザ指定名前空間機能)」を参照してください。
また,DB Connectorの設定の流れについては,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「3.3 リソース接続」を参照してください。
-
1.で設定した別名でDB Connectorをルックアップし,コネクションファクトリ(javax.sql.DataSourceインタフェース)を取得します。
取得したコネクションファクトリからjava.sql.Connectionを取得します。コーディング例を次に示します。
String dbName = <DB Connectorの別名>; InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dbName); Connection con = ds.getConnection();
-
取得したjava.sql.Connectionを使用して,リソースに接続します。
JDBCドライバの提供するjava.sql.ConnectionとAPIは同じです。
- 注意事項
-
DB Connectorを使用する場合,バッチサーバでDB Connectorを開始してからバッチアプリケーションを開始してください。
(2) 既存のバッチアプリケーションから移行する場合
既存のバッチアプリケーション(Javaアプリケーション)から移行する場合,リソースに接続する方法は次の2種類があります。
-
Application Serverで提供するDB Connectorを使用したリソース接続に変更する。
-
JDBCドライバを使用してリソースに接続する(接続方法を変更しない)。
DB Connectorを使用しない場合,バッチアプリケーションのコードを修正する必要はありません。ただし,DB Connectorが提供する機能およびGC制御機能は利用できません。ここでは,リソースの接続方法をDB Connectorに変更する場合の移行方法と,JDBCドライバを使用する場合(接続方法を変更しない場合)の移行方法を説明します。
(a) DB Connectorを使用したリソース接続に変更する
DB Connectorを使用する場合,DB Connectorからjava.sql.Connectionを取得するようバッチアプリケーションを変更してください。変更方法を次に示します。
-
バッチサーバでDB Connectorを設定します。
ユーザ指定名前空間機能を使用して,DB Connectorのオブジェクトに別名を付けてJNDI名前空間に登録します。バッチアプリケーションからデータベースに接続するときには,必ずユーザ指定名前空間機能を使用してください。
別名は,DB Connectorをバッチサーバにデプロイしたあと,Connector属性ファイルで設定します。次の設定例のように,Connector属性ファイルの<resource-external-property>タグに<optional-name>タグを追加して別名を設定します。
設定例
<connector-runtime> : <resource-external-property> <optional-name>DB Connectorの別名</optional-name> </resource-external-property> </connector-runtime>
DB Connectorの別名の付け方については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「2.6 Enterprise BeanまたはJ2EEリソースへの別名付与(ユーザ指定名前空間機能)」を参照してください。
また,DB Connectorの設定の流れについては,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「3.3 リソース接続」を参照してください。
-
バッチアプリケーション内のリソース接続処理のコードをDB Connectorを使用するよう変更します。
変更前のバッチアプリケーションを次に示します。下線部分はConnection取得処理です。この処理を「変更後のバッチアプリケーション」の下線部分の処理に変更してください。「変更後のバッチアプリケーション」の下線部分は,DB ConnectorのConnection取得処理です。
-
変更前のバッチアプリケーション
Class.forName("oracle.jdbc.driver.OracleDriver"); Connection con = DriverManager.getConnection(uri,"user","pass"); con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.executeBatch(); con.commit();
-
変更後のバッチアプリケーション
String dbName = <DB Connectorの別名> InitialContext ic = new InitialContext(); DataSource ds = (DataSource)ic.lookup(dbName); Connection con = ds.getConnection(); con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.executeBatch(); con.commit();
-
DB Connectorから取得したjava.sql.Connectionは,JDBCドライバのjava.sql.Connectionと同様に使用できます。このため,java.sql.Connectionの取得方法だけを変更すれば,ほかのバッチアプリケーションのコードを変更する必要はありません。
- 注意事項
-
DB Connectorを使用する場合,バッチサーバでDB Connectorを開始してからバッチアプリケーションを実行してください。
(b) JDBCドライバを使用してリソースに接続する
JDBCドライバを使用する場合,バッチアプリケーションのコードを修正する必要はありません。ただし,使用するJDBCドライバのライブラリをバッチサーバのクラスパスに追加する必要があります。詳細は,使用するJDBCドライバの設定に従ってください。次に,JDBCドライバのライブラリをバッチサーバのクラスパスに追加する方法を示します。バッチサーバのクラスパスに追加するには,usrconf.cfg(バッチサーバ用オプション定義ファイル)に次の記述を追加します。
add.class.path=<JDBCドライバのライブラリのフルパス>
なお,usrconf.cfg(バッチサーバ用オプション定義ファイル)については,マニュアル「アプリケーションサーバ リファレンス 定義編(サーバ定義)」の「3.2.1 usrconf.cfg(バッチサーバ用オプション定義ファイル)」を参照してください。
(3) リソースに接続するバッチアプリケーションの注意
リソースに接続するバッチアプリケーションを作成するときには,次のことに注意してください。
(a) バッチアプリケーション実行時の注意
バッチアプリケーション実行中には,DB Connectorの停止や設定変更をしないでください。DB Connectorの停止や設定変更は,バッチアプリケーションが終了してから実施します。
(b) コネクションのクローズ
バッチサーバでは,コネクションの自動クローズは実行されません。このため,使用したコネクションは必ずクローズするよう,アプリケーションに実装してください。
(c) JTAのローカルトランザクションの使用
バッチアプリケーションの中で,JTAのローカルトランザクションを使用できます。JTAのローカルトランザクションは,次に示す方法で使用します。
-
次のどちらかの方法でUserTransactionオブジェクトを取得します。
-
ネーミングサービスからルックアップして取得する。
ルックアップ名:HITACHI_EJB/SERVERS/<サーバ名称>/SERVICES/UserTransaction
-
com.hitachi.software.ejb.ejbclient.UserTransactionFactoryクラスのgetUserTransactionメソッドを使用して取得する。
-
-
UserTransactionオブジェクトのbegin()メソッドを呼び出して,トランザクションを開始します。
-
リソースに接続します。
-
UserTransactionオブジェクトのcommit()またはrollback()を呼び出して,トランザクションを決着します。
UserTransactionインタフェースの使用方法の詳細については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「3.4.8 UserTransactionインタフェースを使用する場合の処理概要と留意点」を参照してください。
UserTransaction使用時の注意事項を次に示します。
-
UserTransactionはmainスレッドだけ使用できます。ユーザスレッドでは使用できません。
-
mainスレッドでトランザクションの開始および決着を実施してください。
-
スレッド生成時にトランザクションは引き継がれません。
-
スレッド間でコネクションやコネクションから得られたインスタンス(ステートメントなど)を渡せません。このインスタンスを使用した場合は動作が不正になります。
(d) トランザクションの決着
バッチアプリケーション内でトランザクションを開始した場合は,バッチアプリケーション内で必ず決着処理を実施してください。トランザクションの決着処理を実施しないでバッチアプリケーションを終了すると,タイムアウト時間が経過したあとにトランザクションがロールバックされます。
この場合,簡易構築定義ファイルのejbserver.batch.application.exit.enabledパラメタの指定値によって,次に実行するバッチアプリケーションでトランザクションを開始する時(javax.transaction.UserTransaction#begin())の挙動が異なります。
- ejbserver.batch.application.exit.enabledパラメタで「true」を指定している場合
-
次に実行するバッチアプリケーションでトランザクションを開始できます(javax.transaction.UserTransaction#begin()を受け付けます)。
- ejbserver.batch.application.exit.enabledパラメタで「false」を指定している場合
-
次に実行するバッチアプリケーションでトランザクションを開始できません。この場合,javax.transaction.NotSupportedExceptionが発生し,詳細情報として「KDJE31009-E No nested transaction is supported.」が出力されます。
トランザクションを開始できない状態から回復する場合は,バッチサーバを再起動してください。
ejbserver.batch.application.exit.enabledパラメタの設定については,「2.3.10 実行環境での設定(バッチサーバの設定)」を参照してください。