在項目中碰到了一個應用異常,從表象來看應用僵死。查看Weblogic狀態為Running,內存無溢出,但是出現多次線程堵塞。查看Weblogic日志,發現程序出現多次Time Out。
我們知道,Weblogic會自動檢測線程運行超時,當超過特點時間(默認600S),即認為此線程為堵塞線程。在日志中發現多次堵塞線程,通過查找資料,發現Weblogic在發生多次線程堵塞后,會自動把應用掛起。默認次數為15次。
是什么造成了線程堵塞呢?通過進一步分析日志,我們發現在線程堵塞之前,發生了多次java.sql.SQLRecoverableException: Closed Connection異常。異常情況:
從表現來看是數據庫連接出了異常。我們對數據庫和網絡進行了分析,確定數據庫和網絡都無異常。我們的另外一個應用在Weblogic運行沒有類似問題。
最后在Oracle的論壇上找到了問題的根結,由於我們的應用是自己開發的數據庫連接池,應用和數據庫之間有一層防火牆。防火牆策略是對於1800s未使用的Socket連接將自動關閉。Oracle的日志中也發現Socket異常關閉的異常。我們對應用進行了調整,當連接池中的連接15分鍾不用時,自動回收,問題解決。
http://blog.csdn.net/gavinloo/article/details/12206763
java.sql.SQLException: Io 異常: Connection reset
當數據庫連接池中的連接被創建而長時間不使用的情況下,該連接會自動回收並失效,但客戶端並不知道,在進行數據庫操作時仍然使用的是無效的數據庫連接,這樣,就導致客戶端程序報“ java.sql.SQLException: Io 異常: Connection reset” 或“java.sql.SQLException 關閉的連接”異常。
在配置數據源后面加上
<property name="validationQuery" value="select * from dual"/>
配置后,客戶端在使用一個無效的連接時會先對該連接進行測試,如果發現該連接已經無效,則重新從連接池獲取有效數據庫連接來使用。
JDK1.6:
java.sql
Interface Statement:
setQueryTimeout
void setQueryTimeout(int seconds) throws SQLException
-
Sets the number of seconds the driver will wait for a
Statement
object to execute to the given number of seconds. If the limit is exceeded, anSQLException
is thrown. A JDBC driver must apply this limit to theexecute
,executeQuery
andexecuteUpdate
methods. JDBC driver implementations may also apply this limit toResultSet
methods (consult your driver vendor documentation for details). -
-
- Parameters:
-
seconds
- the new query timeout limit in seconds; zero means there is no limit - Throws:
-
SQLException
- if a database access error occurs, this method is called on a closedStatement
or the condition seconds >= 0 is not satisfied - See Also:
-
getQueryTimeout()