2011-08-22 74 views
0

我正在用新的Tomcat JDBC連接池(org.apache.tomcat.jdbc.pool,版本7.0.20)重新做一些測試。我對使用驗證查詢的理解是,當我例如重新啓動數據庫和池丟失所有連接,它會自動嘗試恢復它們。org.apache.tomcat.jdbc.pool中的驗證查詢

這裏的初始化代碼:

...

PoolProperties p = new PoolProperties(); 
p.setUrl(connString); 
p.setDriverClassName("org.postgresql.Driver"); 
p.setJmxEnabled(true); 
p.setTestWhileIdle(false); 
p.setTestOnBorrow(true); 
p.setValidationQuery("SELECT version();"); 
p.setTestOnReturn(false); 
p.setValidationInterval(30000); 
p.setTimeBetweenEvictionRunsMillis(30000); 
p.setMaxActive(maximumDbConnections); 
p.setInitialSize(1); 
p.setMaxWait(10000); 
p.setRemoveAbandonedTimeout(60); 
p.setMinEvictableIdleTimeMillis(30000); 
p.setMinIdle(minimumIdleDbConnections); 
p.setMaxIdle(maximumIdleDbConnections); 
p.setLogAbandoned(true); 
p.setRemoveAbandoned(true); 
p.setInitSQL("SET application_name = 'My Server'"); 
datasource = new DataSource(); 
datasource.setPoolProperties(p); 

...

在那時我啓動一個定時器,每次它觸發,我從池中獲取連接:

...

Connection conn = App.datasource.getConnection(); 

...

時,即時通訊啓動數據庫,它不會試圖revover連接爲expacted,我總是會收到以下異常:

[2011-08-22 23:50:53,066][871009][ERROR]{DbPollThread - 1} [0144] SQLException while checking for hangig jobs 
java.sql.SQLException: Connection has already been closed. 
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:118) 
    at $Proxy2.prepareStatement(Unknown Source) 
    at org.voxtelo.faxserver.internal.database.FaxDatabaseHandler.resetOrDeactivateHangingJobs(FaxDatabaseHandler.java:404) 
    at org.voxtelo.faxserver.internal.database.FaxDatabaseHandler.pollJobsFromDB(FaxDatabaseHandler.java:884) 
    at org.voxtelo.faxserver.internal.database.FaxDatabaseHandler.access$1(FaxDatabaseHandler.java:882) 
    at org.voxtelo.faxserver.internal.database.FaxDatabaseHandler$PollDatabaseTask.run(FaxDatabaseHandler.java:940) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:680) 

回答

0

最後,我通過我自己發現了問題。代碼

conn = App.datasource.getConnection(); 

當我得到的連接沒有達到了當拋出異常了。所以所有的手術仍然在舊的,斷開的連接上完成。現在我確定conn = App.datasource.getConnection();總是在數據庫操作之前調用,一切都按預期工作。

-1

照顧setValidationInterval(30000),因爲這意味着驗證查詢將每30秒完成一次。我認爲用0設置此值會更安全,每次請求連接時都會觸發驗證查詢。

+0

-1,這是不正確的。他只將「testOnBorrow」設置爲true,這意味着驗證查詢僅在請求連接時運行。 –