sql異常:nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object


連接池滿了:

轉自: http://chivas2008.blogbus.com/logs/28735149.html

http://blog.csdn.net/foamflower/article/details/5369199

解決的辦法有3個

1重啟你的服務器

2在content.xml中,將maxActive設置為零,或者調高它的值

3在你的程序中正確關閉connections 這里有一點要注意要把關閉的語句寫在finally中,如果你寫在try{}中出現異常的話是無法正確關閉的。

 

要象這樣

} catch (SQLException e) { 
/** Exception handling **/ 
} finally { 
try { 
if (stmt != null) 
stmt.close(); 
if (dbConnection != null) 
dbConnection.close(); 
} catch (SQLException e) { 
/** Exception handling **/ 


當然這3個方法里前兩個並不能從根本上解決你的問題,所以還是要好好研究你的程序,一定要將用完的connection放回到池中。

1 問題描述
Web程序在tomcat剛開始運行時速度很快,但過一段時間后發現速度變得很慢。
檢查日志輸出,發現異常如下:
org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted, cause: 
java.util.NoSuchElementException: Timeout waiting for idle object
同時在SQLServer事件探查器中發現,每執行一次sql語句都要產生Audit login事件,語句執行后產生
Audit logout事件。說明每一次tomcat都是重新打開新的連接。
2 問題解決
tomcat 的數據源定義提供了三個參數:
a. 如果設為true則tomcat自動檢查恢復重新利用,沒有正常關閉的Connection.(默認是false)
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
b. 設定連接在多少秒內被認為是放棄的連接,即可進行恢復利用。
<parameter>
<name>removeAbandonedTimeout</name>
<value>60</value>
</parameter>
c. 輸出回收的日志,可以詳細打印出異常從而發現是在那里發生了泄漏
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
B、Timeout waiting for idle object

轉自:http://203.208.37.132/search?q=cache:9TmBcAJrYhQJ:jiangzi87.blog.ccidnet.com/blog.php%3Fdo%3Dshowone%26itemid%3D474468%26typ%3Dblog+java.util.NoSuchElementException:+Timeout+waiting+for+idle+object&cd=5&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy2-dZRxeN0j7d6MJ0Shp7tXcjwyumQ

1、request   too large錯誤 

  在我們應用系統中,有些用戶反映在填寫申請表的時候,有時會出現request too large 的錯誤,導致操作失敗.經查看原因是: 用戶在填寫申請表的時候.我們會擱一定的時間,朝cookies里保存數據.如果cookies里數據過大,就會導致request too large 的錯誤,清除cookies,問題就可以解決.. 
2、Timeout waiting for idle object錯誤
    org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted, cause: 
    java.util.NoSuchElementExceptionTimeout waiting for idle object
是因為連接沒有關閉,導致其他的連接去連接這個老的連接。導致出錯
檢查是否沒有關閉數據庫連接

 

    看到我對於A中紅色顯示的部分,這個參數對於查找原因真的很重要。初看上面的報錯真得讓我一頭霧水,后來配置上這個參數,再運行控制台的報錯信息更加明確,從報錯信息中我找到了運行該功能存在兩個地方連接池泄漏問題:

at com.xxx.action.DoccatalogAction.getDocCatalogListByCatCode(DoccatalogAction.java:1178)


at com.xxx.organization.dao.hibernate.UserHibernateDAOBean.getUserByName(UserHibernateDAOBean.java:54)
 at com.xxx.doc.desktopapp.action.DesktopAppAction.removeAllDataByCategoryList(DesktopAppAction.java:564)

從中可以知道是在哪個方法,哪一行的代碼存在連接池泄漏問題。

 【原因】:

         原來真的是同事寫的代碼中未對session,Connection,Statement等與數據庫相關的連接未釋放。

【解決方法】:

        1、對於session的部分全部加上

            //避免未釋放連接導致連接池耗盡
          Session session =  this.getSession();
          try{
                   //執行代碼   ...
         }finally{
            this.releaseSession(session);
         }

       2、對於數據庫連接

   Session session = listHelper.getSessionFactory().openSession();
   Connection cnn = null;
   Statement state = null;
   ResultSet rs = null;
   try{
      cnn = session.connection();
      state = cnn.createStatement(
      ResultSet.TYPE_SCROLL_INSENSITIVE,
      ResultSet.CONCUR_READ_ONLY);
      String strSQL="";
      strSQL+=" select d.* from tb_datapriv_grant  g , tb_datapriv  d where g.member_id='"+userid+"' ";
      
      rs = state.executeQuery(strSQL);//查詢目錄用戶是否有權限
                 ......
    }finally{

    //關閉rs
    if(null!=rs){
     rs.close();
     rs = null;
    }
    //關閉state
    if(null!=state){
     state.close();
     state = null;
    }
    //關閉cnn
    if(null!=cnn){
     cnn.close();
     cnn = null;
    }
    //關閉session
    if(null!=session){
     session.close();
     session = null;
    }
   }

當然,可能你的項目里獲取session和釋放session的方法和我的並不一樣,因為有的類方法是我們封裝好的。但是相同的是一定要記得釋放。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM