java.sql.SQLException: Already closed

Caused by: java.sql.SQLException: Already closed.
異常:java.sql.SQLException: Already closed.   
        at org.apache.tomcat.dbcp.dbcp.PoolableConnection.close(PoolableConnection.java:84)   
        at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:181)   
        at com.lwjlaser.citation2DB.Citation.controller(Citation.java:84)   
        at com.lwjlaser.citation2DB.DealCitation.doPost(DealCitation.java:46)   
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)   
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)   
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)  
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)   
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)   
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)   
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)   
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)   
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)   
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)   
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)   
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)   
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)   
        at java.lang.Thread.run(Thread.java:619)  
緣由:多是數據庫鏈接時間過長引發的,在鏈接池中,若是長時間沒有使用,它會自動關閉一些長時間沒有使用的鏈接。
涉及到的知識::數據庫鏈接池中總會保持有minIdle這個數目的鏈接,這裏的鏈接若是長時間不使用就會有可能斷開。 

長時間不使用的數據庫鏈接斷開的可能有: 

1.數據庫自己設有這個,自動斷開長時間不使用的鏈接。 

2.網絡問題,在長時間鏈接的過程當中出現過網絡問題。 

3.防火牆問題,防火牆可能會關閉長時間鏈接,但沒有數據流的鏈接。 

出現的異常有:Could not close JDBC Connection,java.sql.SQLException: Already closed.,java.sql.SQLException: 關閉的鏈接, 

出現這種斷開的解決能夠在數據源裏設置一個testOnBorrow爲true.在設置這個參數時還要設置validationQuery這個爲一個最少返回一條數據的select語句。 

org.apache.commons.dbcp.BasicDataSource數據源,很是經常使用。最近在使用時出現點問題。 

DBCP數據源配置好多參數都不是很複雜, 

參數 默認值 描述 
initialSize 0 初始化鏈接:鏈接池啓動時建立的初始化鏈接數量,1.2版本後支持 
maxActive 8 最大活動鏈接:鏈接池在同一時間可以分配的最大活動鏈接的數量, 若是設置爲非正數則表示不限制 
maxIdle 8 最大空閒鏈接:鏈接池中允許保持空閒狀態的最大鏈接數量,超過的空閒鏈接將被釋放,若是設置爲負數表示不限制 
minIdle 0 最小空閒鏈接:鏈接池中允許保持空閒狀態的最小鏈接數量,低於這個數量將建立新的鏈接,若是設置爲0則不建立 
maxWait 無限 最大等待時間:當沒有可用鏈接時,鏈接池等待鏈接被歸還的最大時間(以毫秒計數),超過期間則拋出異常,若是設置爲-1表示無限等待 

還有一個參數說明一下:testOnBorrow true 指明是否在從池中取出鏈接前進行檢驗,若是檢驗失敗,則從池中去除鏈接並嘗試取出另外一個. 

<property name="testOnBorrow"> 
    <value>trues</value> 
   </property> 

這個參數設爲true時,還有一個參數的設置:validationQuery:SQL查詢,用來驗證從鏈接池取出的鏈接,在將鏈接返回給調用者以前.若是指定,則查詢必須是一個SQL SELECT而且必須返回至少一行記錄 

若是testOnBorrow爲true而validationQuery沒有設置,或爲空,或你給的不是一個select語句且沒有數據返回。testOnBorrow也是白設。validationQuery這個的SQL語句通常查詢dual表.經常使用的有SELECT 1 FROM DUAL。最也不要使用SELECT sysdate FROM DUAL.這個語句的效率沒有前面說的一個好。WebLogic 就是使用的SELECT 1 FROM DUAL這個sql語句。 

<property name="testOnBorrow"> 
    <value>true</value> 
   </property> 
   <property name="validationQuery"> 
    <value>SELECT 1 FROM DUAL</value> 
</property> 

要正式系統中使用的數據源最好是用上這個testOnBorrow。這樣能夠保證使用的每一個數據源都不會出現長時間沒有使用中斷後。出現Could not close JDBC Connection這種問題。 

解決辦法: 
<property name="testOnBorrow"> 
    <value>true</value> 
   </property> 
   <property name="validationQuery"> 
    <value>SELECT 1 FROM DUAL</value> 
</property>java

相關文章
相關標籤/搜索