2012-01-06 57 views
5

我想使用ehcache不僅作爲一個緩存,而且作爲一個容器的髒對象,當對象被驅逐/過期時,我想刷新到我的數據庫。在正常處理期間,我使用密鑰在ehcache中查找。如果密鑰不存在,我從數據庫讀取數據並將其放入ehcache。該值實際上是一個複雜的對象,我修改。當ttl /空閒時間/溢出情況發生時,我看到CacheEventListener回調被調用。但是有一個很大的問題。 notifyElementExpired在從緩存中刪除鍵值後調用。所以有一個競爭條件。如果我執行將髒值刷新到notifyElementExpired中的緩存任務並同時在另一個線程中讀取相同的密鑰,則會出現同步問題。第二個線程將不會在ehcache中找到該對象,因此將轉到數據庫,而另一個線程仍在準備刷新。這個用例可以在ehcache中解決嗎?

我試着用寫通過ehcache試驗,我不認爲這也工作。

有沒有解決方法?

我真的很感謝這個問題的好解決方案,即使它涉及到一些其他的緩存機制而不是ehcache。

感謝

+0

我自己找不到任何答案。所以我繼續自己解決它!這裏是我博客的解決方案 - http://blog.readypulse.com/2012/01/08/ehcache-as-a-true-persistent-store-backed-cache/ – 2012-01-08 21:53:20

+1

好的作品TVinodGupta。作爲一個友好的提醒,你可以請你自己發表問題的答案,然後接受答案,以便我們可以關閉這個問題?另外,如果他們解決了您的問題,則需要接受以前問題的答案。 – Zecas 2012-05-28 14:22:31

回答

1

如果你確定與一個純粹的內存緩存,我建議延長Google Guava庫的緩存加載器,例如:在使用之後

public class DBLoader extends CacheLoader<String, String> { 

    @Override 
    public String load(String key) throws Exception { 
     // load a value from the database 
     return value; 
    } 
} 

,是這樣的:

private LoadingCache<String, String> dbCache = CacheBuilder.newBuilder() 
.expireAfterWrite(CACHE_EXPIRE_IN_SECONDS, TimeUnit.SECONDS) 
.build(new DBLoader()); 

String value = dbCache.get(someKey); 


當然,您需要整理好適當的異常處理。

我發現番石榴比正確配置ehcache要簡單得多。

+1

番石榴有它自己的競爭條件:https://github.com/google/guava/issues/1881 – CurtainDog 2015-02-10 05:37:00

相關問題