2010年12月28日火曜日

【Oracle】DataSourceを使用してデータベース接続をキャッシュ

OracleDataSourceにはプール機能(接続のキャッシュ機能)がある。Webコンテナで提供されるDataSourceのプール機能と同じもの。

この機能を使うと、Connectionの取得要求のたびにデータベースとの物理接続を確立する必要がないのでパフォーマンスが向上する。(はず)
普通は、Webコンテナの機能使えばいいのであんまり必要にならないけど、バッチ処理のようにWebコンテナ以外で実行されるアプリの場合には必須の機能だと思う。

キャッシュを使用しない場合

キャッシュを使用しない場合の実装は、【Oracle】DataSourceを使用してデータベース接続と同じ。
// DB接続前のセッション数を出力
printHogeSession("開始前");

OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser("hoge");
dataSource.setPassword("hoge");
dataSource.setURL("jdbc:oracle:thin:@localhost:1521:xe");
Connection connection = dataSource.getConnection();

// getConnection呼び出し後のセッション数を出力
printHogeSession("OracleDataSource.getConnection()呼出し後");
connection.close();

// close呼び出し後のセッション数を出力
printHogeSession("Connection.close()呼出し後");

実行結果

getConnection()の呼出し後には、セッション数が1つになる。
Connection.close()を呼び出すと、物理接続がcloseされるためセッション数は0になる。

この場合、getConnectionの度にOracleとの物理接続が確立されるため、性能的に非常にまずくなる。
開始前
---------------------------------------------


OracleDataSource.getConnection()呼出し後
---------------------------------------------
HOGE             JDBC Thin Client


Connection.close()呼出し後
---------------------------------------------


キャッシュを使用した場合


以下の実装だと、OracleDataSourceが持っているキャッシュ機能を有効化できる。
ただし、OracleDataSourceのキャッシュ機能を使えるのはojdbc14.jarまで。
JDK5やJDK6用のojdbc5、ojdbc6.jarでは別の機能を使用してキャッシュ機能を有効化する必要がる。
// DB接続前のセッション数を出力
printHogeSession("開始前");

OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser("hoge");
dataSource.setPassword("hoge");
dataSource.setURL("jdbc:oracle:thin:@192.168.0.5:1521:xe");

// キャッシュの設定
Properties prop = new Properties();
// 初期容量(デフォルト:0)
prop.setProperty("InitialLimit", "2");
// 最大容量(デフォルト:Integer.MAX_VALUE)
prop.setProperty("MaxLimit", "2");

// 上記で設定した、キャッシュプロパティを設定する。
dataSource.setConnectionCacheProperties(prop);
// setConnectionCachingEnabledを呼び出してキャッシュを有効化する。
dataSource.setConnectionCachingEnabled(true);

Connection connection = dataSource.getConnection();

// getConnection呼び出し後のセッション数を出力
printHogeSession("OracleDataSource.getConnection()呼出し後");
connection.close();

// close呼び出し後のセッション数を出力
printHogeSession("Connection.close()呼出し後");

実行結果

キャッシュ機能が有効になっていることが確認できる。
getConnectionを呼び出したあとでは、初期容量の物理接続が確立されている。
close呼び出し後には、キャッシュを使わなかった時とは異なり物理接続が切断されていないことが確認できる。
物理接続は切断されていなくても論理的な接続は切断されているので、close呼び出し後はDBアクセスはできない。

ちなみに、キャッシュはDataSourceのインスタンス単位にされるので、異なるインスタンスの場合には異なる接続がキャッシュされている。
開始前
---------------------------------------------


OracleDataSource.getConnection()呼出し後
---------------------------------------------
HOGE             JDBC Thin Client
HOGE             JDBC Thin Client


Connection.close()呼出し後
---------------------------------------------
HOGE             JDBC Thin Client
HOGE             JDBC Thin Client