如何在java连接池中检查连接是否关闭

问题描述:

在下面的程序中,我保持在睡眠模式下执行。但是,con obj还没有关闭。如何在java连接池中检查连接是否关闭

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) { 
      } 
     }*/ 
    } 
} 

}

当您使用连接池,你仍然需要明确地关闭致电Connection.close()连接。这将向连接池发信号通知连接再次空闲并且可以返回到连接池。

从连接池获得的Connection不是与数据库的实际物理连接,而是逻辑连接,它是实际物理连接的包装或代理。对于一些任务(最显着的是close()),它将实现稍微不同的行为(以便连接池可以重新使用它),但对于最终用户,它的行为就像是正常连接一样(例如,应关闭所有相关对象)。

你的问题并不十分明确,但我会假设你打算问为什么连接池还没有回收连接,即使你设置了超时。我能想到的几个原因:

  1. 您设置removeAbandonedTimeout为60秒,而你的睡眠只有40000毫秒(40秒),
  2. 的实现可能使用回收“抛弃”连接的合作方式(例如,它可能仅检查何时请求新的Connection,或者当可用连接池变得低时)