0

次のプログラムでは、スリープ モードで実行を続けました。しかし、まだ con obj は閉じられていません。

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
public class ConnPool {

public static void main(String[] args) throws Exception {
    PoolProperties p = new PoolProperties();
    p.setUrl("jdbc:mysql://localhost:3306/users");
    p.setDriverClassName("com.mysql.jdbc.Driver");
    p.setUsername("root");
    p.setPassword("root1");
    p.setJmxEnabled(true);
    p.setTestWhileIdle(false);
    p.setTestOnBorrow(true);
    p.setValidationQuery("SELECT 1");
    p.setTestOnReturn(false);
    p.setValidationInterval(10000);
    p.setTimeBetweenEvictionRunsMillis(10000);
    p.setMaxActive(100);
    p.setInitialSize(10);
    p.setMaxWait(10000);
    p.setRemoveAbandonedTimeout(60);
    p.setMinEvictableIdleTimeMillis(10000);
    p.setMinIdle(10);
    p.setLogAbandoned(true);
    p.setRemoveAbandoned(true);
    p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
            + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
    DataSource datasource = new DataSource();
    datasource.setPoolProperties(p);

    Connection con = null;
    try {
        con = datasource.getConnection();
        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery("select * from emp");
        int cnt = 1;
        while (rs.next()) {
            System.out.println( "Name:" + rs.getString(1)+ " Address:" + rs.getString(2) );
        }
        rs.close();
        st.close();
        Thread.sleep(40000);
        System.out.print(con.isClosed());
    } finally {
       /* if (con != null) {
            try {
                con.close();
            } catch (Exception ignore) {
            }
        }*/
    }
}

}

4

1 に答える 1

3

接続プールを使用する場合でも、を呼び出して接続を明示的に閉じる必要がありますConnection.close()。これにより、接続が再び解放され、接続プールに戻すことができることが接続プールに通知されます。

接続プールから取得するのConnectionは、データベースへの実際の物理接続ではなく、実際の物理接続のラッパーまたはプロキシである論理接続です。一部のタスク(最も注目すべきclose())では、(接続プールが再利用できるように)わずかに異なる動作を実装しますが、エンドユーザーにとっては通常の接続であるかのように動作します(たとえば、すべての依存オブジェクトを閉じる必要があります) 。

あなたの質問はあまり明確ではありませんが、タイムアウトを設定したにもかかわらず、接続プールがまだ接続を再利用していない理由を尋ねるつもりだったと思います。私はいくつかの理由を考えることができます:

  1. を60秒に設定し、removeAbandonedTimeout40000ミリ秒(40秒)だけスリープします。
  2. 実装では、「放棄された」接続を再利用する協調的な方法を使用する場合があります(たとえば、新しいConnection要求があった場合、またはプールで使用可能な接続が少なくなっている場合にのみチェックする場合があります)。
于 2013-03-05T19:13:03.060 に答える