2017-03-23 12 views
0

私はPostgreSQL用のTomcat JDBC接続プールを使用しています。Tomcat JDBC - プールでSQLExceptionが再利用されない場合

プール構成

<Resource name="jdbc/pg_mega" auth="Container" 
     type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" 
     url="jdbc:postgresql://127.0.0.1:6432/db" 
     factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
     username="***" password="****" 
     defaultAutoCommit="true" 
     initialSize="1" 
     maxActive="300" 
     maxTotal="300" 
     maxIdle="20" 
     minIdle="5" 
     maxWait="10000" 
     validationQuery="select 1" 
     validationInterval="30000" 
     testWhileIdle="false" 
     testOnBorrow="true" 
     testOnReturn="false" 
     timeBetweenEvictionRunsMillis="30000" 
     minEvictableIdleTimeMillis="30000" 
     /> 

Javaコード

Connection c = null; 
Statement s = null; 
ResultSet rs = null; 
DataSource ds = ... Get DataSource ... 

while(running) { 

    if (c == null) { 
     try { 
      c = ds.getConnection(); 
     } catch (SQLException exi) { env.l.pe(exi); } 
    } 
    try { 
     s = c.createStatement(); 
     rs = s.executeQuery(q); 
    } catch (SQLException sec) { 
     // close resources 
     if (rs != null) { 
      try { rs.close(); } catch (SQLException sec2) { env.l.pe(sec2); } 
      rs = null; 
     } 
     if (s != null) { 
      try { s.close(); } catch (SQLException sec2) { env.l.pe(sec2); } 
      s = null; 
     } 
     if (c != null) { 
      try { c.close(); } catch (SQLException sec2) { env.l.pe(sec2); } 
      c = null; 
     } 
     continue; 
    } 
    finally { 
    ... close connection, statement, resultset... 
    } 
} 

の一部s.executeQuery(q)中に例外が発生した場合、私は接続、ステートメント、ResultSetを閉じて、(ループの後に継続)、再び接続しようとします。

JDBCプールアクティビティに見られるように、アクティブな接続は例外が発生するたびに増加します。

あなたが例外で終了するプールのDB接続を解放するにはどうすればよいですか?

これはバグでしょうか?

+1

だから、あなたは 'catch'と' finally'に同じ閉じ方を繰り返しますか?単に[try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)を使用するのはなぜですか?すなわち、 'try(c = ds.getConnection(); s = c.createStatement(); rs = s.executeQuery(q)){...}' – pozs

+0

私はコードを単純化します。もともとは、成功するために実行する必要があるいくつかの余分なコードを最後に追加します。 – Dmitry

+0

さて、正しく閉鎖されていないコネクション*がこの原因になる可能性があります。 – pozs

答えて

1

なぜキャッチで接続を閉じますか?あなたは、同じ接続を使用することができますし、whileループの外側で最終的に閉じます。クエリは、例えば不正な形式であれば、あなたのコードは、無限ループを行うことができ、またはデータベースは到達できない場合:

は気をつけてください。

私は、このwhileループをしないことをお勧めしますし、ただやるnは、それぞれの間の待ち時間と再試行(例えば3)をしようとするだろう。

関連する問題