2012-10-29 210 views
8

我一直在瀏覽一段時間,並在過程中咀嚼我的帽子,但無法找到與我的問題完全匹配的東西。
簡而言之,在60秒的不活動狀態下,我得到了極好的堆棧跟蹤(org.apache.tomcat.jdbc.pool.ConnectionPool放棄),這對於幾個服務器端線程來說是正常行爲。
我使用的Tomcat JDBC連接池(org.apache.tomcat.jdbc.pool.DataSource)直接
堆棧跟蹤:WebApp(Tomcat-jdbc)聯合數據庫連接拋棄異常

 
    Oct 29, 2012 8:55:50 PM org.apache.tomcat.jdbc.pool.ConnectionPool abandon 
    WARNING: Connection has been abandoned PooledConnection[[email protected]]:java.lang.Exception 
     at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:967) 
     at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:721) 
     at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:579) 
     at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:174) 
     at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:111) 
     at com.getsom.getConnection(DAO.java:1444) 
     at com.getsom.PreparedConnection.(PreparedConnection.java:48) 
     at com.getsom.Alarms.run(Alarms.java:492) 

我PoolProperties配置如下:

PoolProperties pp = new PoolProperties(); 

    pp.setUrl(someValidUrl); 
    pp.setDriverClassName("com.mysql.jdbc.Driver"); 
    pp.setUsername(someUser); 
    pp.setPassword(somePassword); 
    pp.setJmxEnabled(true); 
    pp.setTestWhileIdle(true); 
    pp.setTestOnBorrow(true); 
    pp.setValidationQuery("SELECT 1"); 
    pp.setTestOnReturn(false); 
    pp.setValidationInterval(30000); 
    pp.setTimeBetweenEvictionRunsMillis(30000); 
    pp.setMaxActive(100); 
    pp.setInitialSize(10); 
    pp.setMaxWait(10000); 
    pp.setMinEvictableIdleTimeMillis(30000); 
    pp.setMinIdle(10); 

    pp.setLogAbandoned(true); 
    pp.setRemoveAbandoned(true); 
    pp.setRemoveAbandonedTimeout(60); 
    pp.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+ 
     "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");  

    setPoolProperties(pp); 

我希望setValidationInterval(30000)能夠救我,因爲30s在連接生命週期中並不多。無論如何,問題是:
我錯過了什麼讓這個連接永遠活着?
一個很好的瞭解:爲什麼我在聲稱連接的函數中超時,儘管它在30秒之前被調用。

回答

30

即使我已經晚了一年,在這個頁面的未來,但我偶然發現,因爲我遇到了類似的問題,也需要一個解決方案。所以我想我會分享最終爲我工作的東西。

在我的情況,發現並通過這篇文章看完之後>>>configuring-jdbc-pool-high-concurrency - 我只是說像這樣我的池配置的攔截器;

"org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer" 

使線路(從張貼上面的代碼),您做setJdbcInterceptors(...)現在應該如下所示;

p.setJdbcInterceptors(
      "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" 
      + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;" 
      + "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"); 

說明 - 從文章中引用,它說;

我們希望確保當我們檢測到連接仍在使用時,我們重置超時計時器,以便連接不會被視爲放棄。我們通過插入攔截器來實現這一點。

每次準備語句或執行查詢時,計時器都會重置連接池上的放棄計時器。這樣...做大量的查詢和更新,不會超時。

銘記你很可能已經克服了這個問題很久以前,我還是希望這有助於其他具有碰到這個頁面類似的問題,就像我做了任何人。

乾杯!

+8

一年回答,兩年接受:) – MonoThreaded

+0

這個答案也是我的解決方案!感謝你們! – Samarland

2

您是否看到過有關PoolConnection的Tomcat網站上的信息。也許你需要的是看物業minEvictableIdleTimeMillis

要回答你的問題,你是超時,因爲要檢查空閒&放棄連接每30秒(見TimeBetweenEvictionRunsMillis),並因爲你設置的evictable空閒超時30秒(見minEvictableIdleTimeMillis),那麼你最終會得到你所擁有的。你說你在空閒時收到這個異常,我懷疑這個異常是關閉空閒連接而不是放棄連接的結果。根據我的理解,放棄連接用於超時查詢(而不是空閒連接)。

就我個人而言,我不想讓連接永遠活着,因爲它們會消耗不必要的資源(即連接到數據庫)。我會玩我最大的連接,驅逐運行和空閒時間,以優化我的要求。我想你可以將這些值設置得足夠大到幾乎永遠!它確實取決於你在做什麼,但...

對不起,我不能在這裏得到更多的幫助。

+0

是的,我已經被廣泛閱讀此。我相信這與放棄而不是驅逐有關。我的假設是ConnectionPool會保持這些連接活着。 – MonoThreaded

+0

當您執行查詢時是否收到錯誤?查詢運行時間超過60秒似乎很奇怪! – ramsinb

+0

沒有。有問題的線程閒置。自從ConnectionPool假定連接被放棄後,問題就出在哪裏。 – MonoThreaded

1

跟蹤配置文件中的 'removeAbandonedTimeout'。這應該是應用程序中最大運行查詢。 othewise它會在執行過程中關閉連接

+0

我有同樣的問題,並已設置removeAbandonedTimeout,並且它不幫助,不幸的是。 –

+0

你能解釋一下如何在Tomcat中「追蹤」資源屬性嗎? – Navigatron

1

中庸之道加入tomcat7在文件的conf/server.xml中

jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; 
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer; 
org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer" 
1

如果您在Tomcat中的context.xml中定義數據源,那麼你應該加入ResetAbandonedTimer象下面這樣:

jdbcInterceptors="ConnectionState;StatementFinalizer;ResetAbandonedTimer" 

後設置ResetAbandonedTimer,問題在我的應用得到了解決,請求你讓我知道是有ResetAbandonedTimer攔截和removeAbandoned =「真」 removeAbandonedTimeout =「60」之間的關係

0

對這個問題的答案是對我很有幫助。

雖然在我的情況,我已經有「ResetAbandonedTimer」 JDBC攔截配置。

不過,我有這樣的跑了比「removeAbandonedTimeout」那我也不再配置的查詢。一旦我增加了「removeAbandonedTimeout」,問題就消失了。