Connection#isClosedでtrueを返すタイミング

ほしがき2017/09/03(日) - 10:30 に投稿

お試し環境

  • Java8
  • PostgreSQL9.6
  • Windows10 Pro

 

Connection#isClosedがtrueになるタイミングが気になった。

CommonsDBCP使ってコネクションプールし、DBサーバ再起動した場合に

プールしているコネクションはもう使えない。

この時、Connection#isClosedはtrue返すよね?っていうのを試した。

まず、Javadocでは以下のように記載されている。

Connection#isClosed

このConnectionオブジェクトがクローズされているかどうかを取得します。接続は、closeメソッドが呼び出されるか、特定の致命的エラーが発生した場合にクローズされます。このメソッドは、Connection.closeメソッドが呼び出されたあとに呼び出された場合にだけtrueを返すことが保証されています。

このメソッドは通常、データベースへの接続が有効か無効かを判定するために呼び出すことはできません。一般のクライアントでは、操作を実行したときにスローされる例外をキャッチすることにより、接続が無効であると判定します。

Connection#closeを明示的に呼び出すとtrue返すけど、他はエラー出たときにtrueを返すかもって言っています。

でだ。エラー処理を書く時に上記のタイミングでtrueを返してくれればいいなと思って試した。

もちろんこれはJDBC?DBCP?実装依存なので全てのDB(OracleとかMySQL)でそうなるとは言い切れないので参考程度に。

 

やりたいことはコネクションプールからコネクション取得→途中でDBサーバ再起動でコネクションが無効な状態→Connection#isClosedの状態確認

結果としてはisClosedがtrueになりました。

以下、ソースとか

  • Maven

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 --> <dependency>     <groupId>org.apache.commons</groupId>     <artifactId>commons-dbcp2</artifactId>     <version>2.1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <dependency>     <groupId>org.postgresql</groupId>     <artifactId>postgresql</artifactId>     <version>42.1.4</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils --> <dependency>     <groupId>commons-dbutils</groupId>     <artifactId>commons-dbutils</artifactId>     <version>1.7</version> </dependency>

 

 

  • DBCP

driverClassName=org.postgresql.Driver url=jdbc:postgresql://localhost:5433/test username=postgres password=postgres validationQuery=select 1 maxWait=1000 initialSize=3 maxActive=3 maxIdle=3  

 

 

  • App.java

package test.dbcp.connection;

import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSourceFactory; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.handlers.MapListHandler;

public class App {     public static void main( String[] args ) {         try {             QueryRunner runner = new QueryRunner();

            Properties properties = new Properties();             InputStream is = ClassLoader.getSystemResourceAsStream("dbcp.properties");             properties.load(is);             DataSource ds = BasicDataSourceFactory.createDataSource(properties);

            ResultSetHandler<List<Map<String, Object>>> resultSet = new MapListHandler();             Connection con = null;             for (int i = 0; i < 100; i++) {

                // ループしている最中にPostgresのサービスを停止→開始を行う                 try {                     con = ds.getConnection();                     List<Map<String, Object>> ret = runner.query(con, "select * from batch_history", resultSet);                     System.out.println(ret.size());                 } catch (SQLException e) {                     e.printStackTrace();                 } finally {                     System.out.println(con.isClosed());                     DbUtils.closeQuietly(con);                 }                 Thread.sleep(500);             }         } catch (Exception e) {             e.printStackTrace();         }     } }

 
タグ