簡體   English   中英

WebApp(Tomcat-jdbc)池化數據庫連接拋出放棄異常

[英]WebApp (Tomcat-jdbc) Pooled DB connection throwing abandon exception

我一直在瀏覽 SO 一段時間,並在此過程中咀嚼我的帽子,但找不到與我的問題完全匹配的內容。
簡而言之,在 60 秒不活動后,我得到了極好的堆棧跟蹤(org.apache.tomcat.jdbc.pool.ConnectionPool abandon),這是幾個服務器端線程的正常行為。
我直接使用 Tomcat JDBC 連接池 (org.apache.tomcat.jdbc.pool.DataSource)
堆棧跟蹤:

    Oct 29, 2012 8:55:50 PM org.apache.tomcat.jdbc.pool.ConnectionPool abandon
    WARNING: Connection has been abandoned PooledConnection[com.mysql.jdbc.JDBC4Connection@1ad2916]: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) 能拯救我,因為 30 秒在連接生命周期中並不多。 無論如何,問題是:
我錯過了什么才能永遠保持這種聯系?
很高興知道:為什么我在聲明連接的函數中超時,盡管它是在 30 秒前調用的。

盡管我遲到了 1 年多才來到這個頁面,但我在這里偶然發現了因為我遇到了類似的問題並且也需要解決方案。 所以我想我會分享最終對我有用的東西。

就我而言,在找到並通讀這篇文章后 >>> 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");

解釋-引用文章,它說;

我們要確保當我們檢測到連接仍在使用時,我們會重置超時計時器,這樣連接就不會被視為已放棄。 我們通過插入一個攔截器來做到這一點。

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

記住你很可能很久以前就解決了這個問題,我仍然希望這能幫助其他遇到類似問題的人,就像我一樣。

干杯!

您是否在 Tomcat 網站上看到過有關PoolConnection的信息。 也許您需要查看屬性minEvictableIdleTimeMillis

要回答您的問題,您正在超時,因為您每 30 秒檢查一次空閑和放棄連接(請參閱TimeBetweenEvictionRunsMillis ),並且由於您將可驅逐的空閑超時設置為 30 秒(請參閱minEvictableIdleTimeMillis ),那么您最終得到了您所擁有的。 你說過你在空閑時收到這個異常,我懷疑這個異常是關閉空閑連接而不是放棄連接的結果。 根據我的理解,放棄連接用於比預期查詢超時更長的時間(與空閑連接相反)。

就我個人而言,我不希望連接永遠存在,因為它們會不必要地消耗資源(即與數據庫的連接)。 我會玩弄我的最大連接數、驅逐運行和空閑時間來優化我自己的需求。 我想您可以將這些值設置得足夠大,幾乎可以永遠存在。 這確實取決於你在做什么......

對不起,我不能在這里提供更多幫助。

只需在 tomcat7 conf/server.xml 或 context.xml 中存在資源標記的地方添加以下條目。

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

在配置文件中跟蹤“removeAbandonedTimeout”。 這應該是應用程序中的最大運行查詢。 否則它將在執行過程中關閉連接

如果您在 tomcat 的 context.xml 中定義數據源,那么您應該像下面這樣添加 ResetAbandonedTimer:

jdbcInterceptors="ConnectionState;StatementFinalizer;ResetAbandonedTimer"

設置 ResetAbandonedTimer 后,問題在我的應用程序中得到解決,請求您讓我知道 ResetAbandonedTimer 攔截器與 removeAbandoned="true" removeAbandonedTimeout="60" 之間是否有任何關系

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

盡管就我而言,我已經配置了“ResetAbandonedTimer”JDBC 攔截器。

但是,我的查詢運行時間比我還配置的“removeAbandonedTimeout”長。 一旦我增加了“removeAbandonedTimeout”,問題就消失了。

有一個類似的問題,即 tomcat 正在關閉 JDBC 連接,因為它因為事務花費了很長時間而被放棄。

通過意識到abandonedidle是不同的並通過設置解決它: spring.datasource.tomcat.removeAbandonedTimeout: 86400 #seconds

我可以看到這個線程是舊的,但我有一個類似的問題,我最終找到了導致它的原因,所以如果它可以幫助別人,我想分享一下:

我使用了來自寧靜網絡服務的連接。 在服務器端處理客戶端請求的接口中,我不小心在方法簽名中放入了“throws IOException”:

@GET
@Path("/databases")
@Produces(MediaType.APPLICATION_JSON)
public String getAllDatabases() throws IOException {

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM