2013-03-05 394 views
0

在下面的程序中,我保持在睡眠模式下執行。但是,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) { 
      } 
     }*/ 
    } 
} 

}

回答

3

當您使用連接池,你仍然需要明確地關閉致電Connection.close()連接。這將向連接池發信號通知連接再次空閒並且可以返回到連接池。

從連接池獲得的Connection不是與數據庫的實際物理連接,而是邏輯連接,它是實際物理連接的包裝或代理。對於一些任務(最顯着的是close()),它將實現稍微不同的行爲(以便連接池可以重新使用它),但對於最終用戶,它的行爲就像是正常連接一樣(例如,應關閉所有相關對象)。

你的問題並不十分明確,但我會假設你打算問爲什麼連接池還沒有回收連接,即使你設置了超時。我能想到的幾個原因:

  1. 您設置removeAbandonedTimeout爲60秒,而你的睡眠只有40000毫秒(40秒),
  2. 的實現可能使用回收「拋棄」連接的合作方式(例如,它可能僅檢查何時請求新的Connection,或者當可用連接池變得低時)