在項目中碰到了一個應用異常,從表象來看應用僵死。查看Weblogic狀態爲Running,內存無溢出,可是出現屢次線程堵塞。查看Weblogic日誌,發現程序出現屢次Time Out。html
咱們知道,Weblogic會自動檢測線程運行超時,當超過特色時間(默認600S),即認爲此線程爲堵塞線程。在日誌中發現屢次堵塞線程,經過查找資料,發現Weblogic在發生屢次線程堵塞後,會自動把應用掛起。默認次數爲15次。java
是什麼形成了線程堵塞呢?經過進一步分析日誌,咱們發如今線程堵塞以前,發生了屢次java.sql.SQLRecoverableException: Closed Connection異常。異常狀況:sql
從表現來看是數據庫鏈接出了異常。咱們對數據庫和網絡進行了分析,肯定數據庫和網絡都無異常。咱們的另一個應用在Weblogic運行沒有相似問題。數據庫
最後在Oracle的論壇上找到了問題的根結,因爲咱們的應用是本身開發的數據庫鏈接池,應用和數據庫之間有一層防火牆。防火牆策略是對於1800s未使用的Socket鏈接將自動關閉。Oracle的日誌中也發現Socket異常關閉的異常。咱們對應用進行了調整,當鏈接池中的鏈接15分鐘不用時,自動回收,問題解決。網絡
http://blog.csdn.net/gavinloo/article/details/12206763app
當數據庫鏈接池中的鏈接被建立而長時間不使用的狀況下,該鏈接會自動回收並失效,但客戶端並不知道,在進行數據庫操做時仍然使用的是無效的數據庫鏈接,這樣,就致使客戶端程序報「 java.sql.SQLException: Io 異常: Connection reset」 或「java.sql.SQLException 關閉的鏈接」異常。post
在配置數據源後面加上測試
<property name="validationQuery" value="select * from dual"/>this
配置後,客戶端在使用一個無效的鏈接時會先對該鏈接進行測試,若是發現該鏈接已經無效,則從新從鏈接池獲取有效數據庫鏈接來使用。url
void setQueryTimeout(int seconds) throws SQLException
Statement
object to execute to the given number of seconds. If the limit is exceeded, an
SQLException
is thrown. A JDBC driver must apply this limit to the
execute
,
executeQuery
and
executeUpdate
methods. JDBC driver implementations may also apply this limit to
ResultSet
methods (consult your driver vendor documentation for details).
seconds
- the new query timeout limit in seconds; zero means there is no limit
SQLException
- if a database access error occurs, this method is called on a closed
Statement
or the condition seconds >= 0 is not satisfied
getQueryTimeout()