Java、データベース接続(Commons DBCP、c3p0も含め)
JavaでJDBCをつかったDB接続
参照系
// PostgreSQL JDBC Driverのロード Class.forName("org.postgresql.Driver"); Connection conn = null; Statement stmt = null; try { // 接続 conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/TestDB", "username", "password"); // ステートメントを作成 stmt = conn.createStatement(); // 問合せの実行 ResultSet rset = stmt.executeQuery("select param1, param2 from test"); // 問合せ結果の表示 while (rset.next()) { // 列番号による指定 System.out.println(rset.getString(1) + "\t" + rset.getString(2)); } stmt.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } finally { // 保険に if(stmt !=null && !stmt.isClosed()) { stmt.close(); } if(conn !=null && !conn.isClosed()) { conn.close(); } }
更新系
// PostgreSQL JDBC Driverのロード Class.forName("org.postgresql.Driver"); try { // 接続 Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/TestDB", "username", "password"); // オートコミットをオフ conn.setAutoCommit(false); // ステートメントを作成 Statement stmt = conn.createStatement(); // 問合せの実行 int insertNum = stmt.executeUpdate("insert into test values(〜"); // コミット conn.commit(); } catch (SQLException e) { // 更新に失敗したのでロールバック conn.rollback(); e.printStackTrace(); } finally { if(stmt !=null && !stmt.isClosed()) { stmt.close(); } if(conn !=null && !conn.isClosed()) { conn.close(); } }
- ResultSet rset = stmt.executeUpdate("insert into test values(〜");
- 更新系のクエリを実行する際は「executeQuery」。
- conn.rollback();
Commons DBCP
DBCPはDataBase Connection Poolingの略だと思う。ちょっとデータソースファクトリーというのを使ってみる。
Properties properties = new Properties(); InputStream is = ClassLoader.getSystemResourceAsStream("dbcp.properties"); properties.load(is); DataSource ds = BasicDataSourceFactory.createDataSource(properties); Connection con = ds.getConnection(); // con.close();
「con.close();」を叩いちゃったら、DBPCで管理しているコネクションを破棄してしまうように見えるが「ds.getConnection()」で取得したConnectionオブジェクトはJDBCの「java.sql.Connection」実装クラスをさらにラップしており、実際にはコネクションが解放される訳ではなく、プールに戻ってる模様。
・dbcp.properties
driverClassName=org.postgresql.Driver url=jdbc:postgresql://localhost:5432/TestDB username=username password=password initialSize=30 maxActive=100 maxIdle=30 maxWait=5000 validationQuery=select count(*) from test
ベーシックデータソースというのを使ってみる。
BasicDataSource basicDataSource = new BasicDataSource(); basicDataSource.setDriverClassName(“org.postgresql.Driver”); String url = new StringBuffer(“jdbc:postgresql://”).append(”localhost:5432/TestDB”).toString(); basicDataSource.setUrl(url); /* データベースのユーザー名 */ basicDataSource.setUsername(“username”); /* データベースのパスワード */ basicDataSource.setPassword(“password”); /* データベース最大接続数 */ basicDataSource.setMaxActive(100); dataSource = (DataSource) basicDataSource;
基本設定
- username
- DB接続ユーザ名
- password
- DB接続パスワード
- url
- DB接続URL(JDBC)
- driverClassName
- 使用するJDBCドライバクラスのフルネーム
- connectionProperties
- 接続に必要なプロパティを記述
プロパティ名(1)=プロパティ値(1);プロパティ名(2)=プロパティ値(2);
接続設定
コネクションプール設定
- initialSize
- コネクションプールの初期コネクションの数(デフォルト:0)
- maxActive
- 最大Activeコネクション数(デフォルト:8)
- Activeコネクションとはコネクションプールから業務ロジックにより取得されたコネクションの数(Begin-Tranしてるコネクションの数)
- maxIdle
- 最大Idleコネクション数(デフォルト:8)
- Idleコネクションとは業務ロジックで使用されていないプールされたコネクションのこと
- つまりアプリケーション全体でDBへ張っているコネクション数は最大「maxActive + maxIdle」となる可能性がある?
- コネクションがコネクションプールに返却される際、コネクションプールのサイズがmaxIdle以上の場合、コネクションはプールへ返却されずに解放される
- 負の値を指定すると無制限(一度確立したコネクションは解放されることはない)
- maxWait
- コネクション取得の待ち時間(デフォルト:-1(永久に待つ))
- プールされているコネクションが存在しない場合、プールにコネクションが返却されるのを待つ時間
- validationQuery
- testOnBorrow
- プールからコネクションを取得する前に有効性の確認をする設定(デフォルト:true)
- 「validationQuery」が指定されていない場合はfalse
- 有効性が確認できない場合は「SQLException」が投げられる
- testOnReturn
- プールへコネクションを返す前に有効性の確認をする設定(デフォルト:false)
- 「validationQuery」が指定されていない場合はfalse
- 有効性が確認できない場合はコネクションが破棄される
- connectionInitSqls
- ConnectionFactoryがコネクションを初回作成した際に使用されるvalidate用のSQL
コネクション監視スレッド設定
- timeBetweenEvictionRunsMillis
- プール内のIdleコネクションを指定時間間隔で監視(デフォルト:-1ms)
- 0以下の値では監視スレッドは起動しない
- 監視スレッドは以下の処理を行う
- Idleコネクションの確保(minIdleの設定分確保)
- Idleコネクションの有効性の確認(testWhileIdleがtrueの時のみ有効)
- Idleコネクションの生存期間の確認(minEvictableIdleTimeMillisにて設定)
- minIdle
- 最少Idleコネクション数(デフォルト:0)
- 「timeBetweenEvictionRunsMillis」が1以上の場合のみ有効
- testWhileIdle
- Idleコネクションの有効性の確認(デフォルト:false)
- 「validationQuery」が指定されていない場合はfalse
- 「timeBetweenEvictionRunsMillis」の時間毎に最大「numTestsPerEvictionRun」件の確認用SQLが発行される
- minEvictableIdleTimeMillis
- Idleコネクションの生存期間(デフォルト:30*60*1000ms)
- 「timeBetweenEvictionRunsMillis」が1以上の場合のみ有効
- 指定した期間Idleコネクションが使用されなかった場合削除される
- numTestsPerEvictionRun
- 1回の監視処理でチェックするIdleコネクション(プールされているコネクション)の最大数(デフォルト:3)
- 「timeBetweenEvictionRunsMillis」が1以上の場合のみ有効
- 負の値を設定した場合、Idleコネクション数の「何分の一をチェックする」という割合で指定可能
- 「-3」→1/3、「-2」→1/2
接続リーク対策
Prepared Statement設定
- poolPreparedStatements
- Prepared Statementのプーリングを有効か指定(デフォルト:false)
- maxOpenPreparedStatements
- プール内に保管する最大Prepared Statement数を指定(デフォルト:0(無制限))
Commons DBCP個人的神サイト
http://www.ksky.ne.jp/~snbhsmt/commons-dbcp.html
http://www.limy.org/program/java/commons_dbcp.html
c3p0
Commons DBCP以外にもある。以下設定メモ。
コネクションプールの基本設定
- acquireIncrement
- デフォルト:3
- 接続プールが使い尽くしたとき、一回同時に新たに取得するコネクション数
- initialPoolSize
- デフォルト:3
- 初期状態のコネクション数。minPoolSize と maxPoolSizeの間の数字で設定する必要がある。
- maxPoolSize
- デフォルト:15
- 接続プールに保持できる最大コネクション数
- maxIdleTime
- デフォルト:0 (s) ※0は永久に残ることを意味する
- 使用されないコネクションが生存する時間
- minPoolSize
- デフォルト:3
- 接続プールに保持する最小コネクション数。
コネクションプールサイズと生存期間の設定
- maxConnectionAge
- デフォルト:0 (s) ※0は永久に残ることを意味する
- 接続プール内のコネクションの生存期間。生存期間外のコネクションが破棄される
- maxIdleTime
- デフォルト:0 (s)
- 最大アイドル時間。指定される時間内で使用されていなければコネクションが破棄されます。
- maxConnectionAgeとの違いは、maxConnectionAgeは絶対時間を指定するのに対し、maxIdleTimeは相対時間を指定
- maxIdleTimeExcessConnections
コネクションの確認を行う設定
- automaticTestTable
- デフォルト:null
- 接続テスト用テーブル名
- c3p0は自動的に指定される名前のテーブルを生成し、接続を行う際に、このテーブルを用いてテストを行う
- また、automaticTestTableが設定される場合、c3p0はテスト用クエリ語句を自動的生成し、preferredTestQuery設定が無視される
- connectionTesterClassName
- デフォルト:com.mchange.v2.c3p0.impl.DefaultConnectionTester
- 接続テストクラス。 ConnectionTesterまたはQueryConnectionTesterインタフェースを実装する必要がある。
- また、デフォルトのテスタークラスでテストで使用するクエリは「preferredTestQuery」にて設定する
- idleConnectionTestPeriod
- デフォルト:0 (s) ※0はチェックしないことを意味する
- 接続プール内のアイドル状態のコネクションを時間間隔「0以外の数字」でチェックする
- preferredTestQuery
- デフォルト:null
- デフォルトのConnectionTester(ConnectionTesterClassのデフォルト設定)を使用してコネクションを確認するためのクエリを定義
- testConnectionOnCheckin
- デフォルト:false
- trueの場合、コネクション利用開始時にコネクションの有効性を確認する
- testConnectionOnCheckout
- デフォルト:false
- trueの場合、コネクション利用終了時にコネクションの有効性を確認する
ステートメントプールの設定
- maxStatements
- デフォルト:0
- c3p0のグローバルPreparedStatementキャッシュ・サイズ
- maxStatementsとmaxStatementsPerConnectionともに0の場合、statementキャッシュは無効。
- maxStatementsは全コネクションのStatementsキャッシュの数を定義するため、アプリケーション全体で頻繁に使用されるPreparedStatementsの数×maxPoolSize で得られる数値を設定すれば妥当。
- maxStatementsPerConnection
- デフォルト:0
- c3p0個々のコネクションPreparedStatementsキャッシュ・サイズ。
- アプリケーションのdistinct PreparedStatementsの数+2,3が妥当。
- statementCacheNumDeferredCloseThreads
DB接続障害からの復旧設定
- acquireRetryAttempts
- デフォルト:30
- 新たにコネクションを取得するのに失敗したときのリトライ回数
- acquireRetryDelay
- デフォルト:1000 (ms)
- リトライ間隔時間
- breakAfterAcquireFailure
- デフォルト:false
- true:コネクションの取得ができなかった場合、DataSource自体は閉鎖され、接続不可になる
- false:コネクションの取得ができなかった場合、すべてのスレッドにExceptionを投げるが、DataSourceは有効のままで保持し続き、次回のgetConnection()の時も、新たなコネクションの取得を試みる
カスタマイズによるコネクションライフサイクルの管理設定
- connectionCustomizerClassName
- デフォルト:null
- コネクション拡張クラス。ConnectionCustomizerインタフェースを実装したフルパスのクラス名を指定する。
トランザクションのハンドリング設定
- autoCommitOnClose
- デフォルト:false(ロールバックする)
- コネクションをクローズするとき、すべての未確定の操作をコミットするかどうかを設定
- forceIgnoreUnresolvedTransactions
アプリケーション故障時のデバックと回避の設定
- debugUnreturnedConnectionStackTraces
- unreturnedConnectionTimeout