2011-07-30 28 views
1

我們有一個spring bean,它在啓動時從Postgresql(8.4)數據庫加載應用程序消息。 豆的定義是這樣的: <豆....初始化方法=「loadMessages」 >意外的結果集在Spring Web應用程序中關閉異常

的代碼相當直截了當:

get a connection (we are using a dbcp pool) 
Create a statement (plain jdbc, nothing special) 
execute the query, get the result set 
while(resultSet.next())){ 
    cacheMap.put(resultSet.getString("column1"), resultSet.getString("column2"));  
} 

代碼有時會拋出一個結果是內部封閉例外while在應用程序啓動時循環。 它工作正常,沒有任何異常使用Postgresql 8.4.2,但在使用Postgresql 8.4.8時大部分時間(並非總是)拋出異常。
我們在運行Windows 7或2008服務器的4臺不同計算機上測試它,Tomcat 6.0.32,最新版本的Java 1.6,所有數據庫服務器都運行在同一臺機器上。 結果集包含大約8000行(兩列;字符變化(200)和字符變化(1000))。 這裏有什麼可能是錯誤的?

  • 在完成結果集處理之前,池是否可能關閉連接或重新使用連接?
  • 或者它可以是與數據庫版本相關的東西?

順便說一句,我們改變了代碼來加載消息時,他們是第一次使用,而不是應用程序啓動,它工作正常。所以只有在啓動時使用init-method調用代碼時纔會引發此異常。

在此先感謝

回答

0

我最初的想法是,你可以使用Spring容器bean之前已經完全初始化。這有時會導致不一致的行爲(當配置更改或庫更改時,可能不會按相同順序初始化)。您的最後一段還指出了依賴性初始化問題。

Spring使用ref配線來決定首先應該初始化哪些bean。但是,如果你的init方法訪問容器bean(而不是使用注入的bean),Spring不知道這個,你可能正在訪問一個已經構建但尚未初始化的bean。緩存和靜態初始化器似乎是這種悲傷的典型候選者。

在構建Spring容器之後,將緩存構建活動移動到某個時間的解決方案對我來說似乎是一個很好的解決方案。如果這是一個依賴初始化問題,你可以猜測哪個bean不完整(比如連接池),你可以在你的bean配置文件中使用「depends-on」來先強制其他bean的初始化。

如果這是一個初始化問題,那麼我希望當你得到「結果集關閉」異常時,它總是在while(resultSet.next()))語句的第一個命中,你將有緩存中沒有任何內容。任何一件事情都沒有被正確初始化,並且它立即失敗,或者事情做了正確的初始化並且你的緩存被填充。如果緩存部分填充並且結果集錯誤發生在讀取結果集的過程中,那麼整個初始化理論就不再有意義了。

+0

感謝您的回答。我們只使用spring管理的bean。結果設置關閉的異常不會引發第一個結果。緩存得到部分填充。例如,如果我們通常有8k行,處理2k行左右(不是實際的數字)後拋出異常。不知何故結果集,我認爲該語句在循環過程中被關閉。文檔說,如果在同一個連接上執行另一個查詢,語句會被關閉。也許連接池將連接交給另一個執行另一個查詢的線程。但是這種情況對我來說沒有意義。 –

相關問題