2013-07-03 38 views
0

我的環境是一個運行在Tomcat 7中的Web應用程序,我的一個前端處理程序爲某個目的從數據庫中檢索一些整數。在不同用戶的不同請求期間,可能會檢索到相同的整數,這就是爲什麼我想在處理程序中添加一個簡單的Map作爲靜態字段來緩存已讀取的整數。靜態地圖作爲緩存丟失或沒有設置值

現在的問題是,在請求期間,我發現有些值被緩存,其他值不是。看起來,某些對地圖的放置電話會被忽略,或者這些值不會被存儲或進行任何操作。如果我在Eclipse中調試應用程序,則可以看到對put的調用被訪問,但之後新獲取的值不是Cache的一部分,至少Eclipse不顯示它。如果最後一次獲取的值需要在同一個請求中獲取兩次,那麼第二次調用明顯會觸發緩存並避免訪問數據庫,即使Eclipse沒有將所需的值顯示爲緩存的一部分。如果在另一個請求中需要相同的值,則會再次從數據庫中提取該值,並將其存儲在緩存中,但未在Eclipse中顯示,但可用於在同一請求中進行檢索。

我真的迷失在這裏,好像我在做一些非常錯誤的事情。但是我的web應用程序中已經有其他靜態字段作爲緩存,並且沒有看到這些奇怪的行爲。但那些沒有地圖,只有自定義或整數對象。

private static Map<Integer, Integer> dirsOwnerCache = new TreeMap<Integer, Integer>(); 
private static Map<Integer, Integer> docsOwnerCache = new TreeMap<Integer, Integer>(); 

public static void someMethod() 
{ 
    [...] 
    Integer ownerId = null; 
    sync: synchronized(tabelle.equals("ordner") ? Util.dirsOwnerCache : Util.docsOwnerCache) 
    { 
     ownerId = tabelle.equals("ordner") ? Util.dirsOwnerCache.get(dsid) : 
               Util.docsOwnerCache.get(dsid); 
     if (ownerId != null) 
     { 
      break sync; 
     } 

     // fetching from database 
     [...] 
     ownerId = rs.getInt("besitzer_id"); 
     rs.close(); 
     stmt.close(); 

     if (tabelle.equals("ordner")) 
     { 
      Util.dirsOwnerCache.put(dsid, ownerId); 
     } 
     else 
     { 
      Util.docsOwnerCache.put(dsid, ownerId); 
     } 
    } 
    [...] 
} 

我會很感激任何提示,我可以找到問題。謝謝!

回答

0

我想我發現了什麼問題:我的環境有點特殊,因爲我的Web應用程序由一個Servlet/JSP-Frontend和一個Axis 2 SOAP服務組成,作爲後端。爲了有選擇地擺脫SOAP,我們決定使用一些ClassLoader操作將Axis 2服務作爲本機Java類提供,尤其是使用URLClassLoader以及後端路徑和我們使用的所有庫等,並使用URLClassLoader本地加載後端類。 java.lang.ClassLoader.loadClass表示通常在加載類之前使用findLoadedClass,以查看它是否已在之前加載並且不再加載它。在我的環境中或者我如何使用URLClassLoader似乎不是這種情況,因爲每次請求期間每次調用都會產生一個新的類對象。正因爲如此,靜態字段是在請求期間新創建的。雖然我不知道爲什麼在Eclipse中看起來我的緩存的某些值在請求期間是持久的,也許某些加載的類以某種方式被URLClassLoader緩存。但是,在使用URLClassLoader之前,我將自己的靜態映射添加爲一次加載類的緩存,現在我的後端緩存正常工作:它們的值在請求期間保持不變,並且在Eclipse調試器中正確可見。