2012-09-12 46 views
2

为了满足业务服务需求,我的工作需要将某个SQL DB中的某些数据保留在缓存中。这些数据就像系统参数,可以通过管理应用程序进行更改。使用CacheEventListener在notifyExpired上刷新缓存

该规范告诉我需要每2分钟刷新一些数据。

我已经使用Spring 3 + Hibernate 3.6 + ehcache来做到这一点。

对于2分钟刷新的要求,我已经配置我的ehcache.xml中是这样的:

<cache name="xxx.yyy.zzz.domain.Parameter" 
    maxEntriesLocalHeap="1000" eternal="false" timeToIdleSeconds="0" 
    timeToLiveSeconds="120" statistics="true"> 
    <cacheEventListenerFactory class="xxx.yyy.zzz.listner.CacheListnerFactory" properties="bean=myCacheEventListner" listenFor="all"/> 

    <persistence strategy="localTempSwap" /> 

</cache> 

我的听众通知方法被调用时,这个缓存exipre ..不错。但从文件。的ehcache,我读到删除块,直到通知方法返回!!!!我想用这种通知方法回调数据库并重新加载缓存中的数据!

我如何使用cacheEventListener实现此行为。

这里是我的监听器代码:

@Override 
public void notifyElementExpired(Ehcache arg0, Element arg1) { 
    log.info("CACHE EXPIRED : " + arg0.getName()); 
    log.info("CACHE EXPIRED ELEMENT: " + arg1); 
    log.info("RELOADING CACHE"); 
    List<Parameter> params = servParam.getAllParameter(); 
    for (Parameter p : params) { 
     servParam.getParameter(p.getCodeParam(), p.getCodeMarche()); 
    } 


} 

,这是从我的JUnit日志的一部分:

<ENTER testGetParameterExpired> 
<enter - get parameters - code param = PAIEMENT_FACTURE_DELAI_MIN code marche = P> 
<CACHE EXPIRED : [ name = auport.commun.shared.domain.Parameter status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 1000 maxEntriesLocalDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 5 timeToIdleSeconds = 0 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: auport.commun.shared.listner.MyCacheEventListner net.sf.ehcache.statistics.LiveCacheStatisticsWrapper hitCount = 2 memoryStoreHitCount = 2 diskStoreHitCount = 0 missCountNotFound = 5 missCountExpired = 1 maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]> 
<CACHE EXPIRED ELEMENT: [ key = sql: select parameter0_.cod_paap as cod1_0_, parameter0_.cod_mrch as cod2_0_, parameter0_.TMS_MAJ as TMS3_0_, parameter0_.NOM_ANGL_PAAP as NOM4_0_, parameter0_.nom_fran_paap as nom5_0_, parameter0_.NOM_UTLR_MAJ as NOM6_0_, parameter0_.NUM_UTLR_MAJ as NUM7_0_, parameter0_.PRN_UTLR_MAJ as PRN8_0_, parameter0_.VAL_PAAP as VAL9_0_ from TABCOMMUN.TPAAP parameter0_ where parameter0_.cod_paap=? and parameter0_.cod_mrch=?; parameters: PAIEMENT_FACTURE_DELAI_MIN, P, ; named parameters: {}, value=[5519186315907073, [Ljava.lang.Object;@1f6d2e3], version=1, hitCount=1, CreationTime = 1347457596657, LastAccessTime = 1347457596750 ]> 
<RELOADING CACHE> 
<enter - get all parameters> 
<CACHE EXPIRED : [ name = auport.commun.shared.domain.Parameter status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 1000 maxEntriesLocalDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 5 timeToIdleSeconds = 0 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: auport.commun.shared.listner.MyCacheEventListner net.sf.ehcache.statistics.LiveCacheStatisticsWrapper hitCount = 2 memoryStoreHitCount = 2 diskStoreHitCount = 0 missCountNotFound = 6 missCountExpired = 2 maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]> 
<CACHE EXPIRED ELEMENT: [ key = sql: select parameter0_.cod_paap as cod1_0_, parameter0_.cod_mrch as cod2_0_, parameter0_.TMS_MAJ as TMS3_0_, parameter0_.NOM_ANGL_PAAP as NOM4_0_, parameter0_.nom_fran_paap as nom5_0_, parameter0_.NOM_UTLR_MAJ as NOM6_0_, parameter0_.NUM_UTLR_MAJ as NUM7_0_, parameter0_.PRN_UTLR_MAJ as PRN8_0_, parameter0_.VAL_PAAP as VAL9_0_ from TABCOMMUN.TPAAP parameter0_; parameters: ; named parameters: {}, value=[5519186315202560, [Ljava.lang.Object;@1286b10, [Ljava.lang.Object;@8d2280, [Ljava.lang.Object;@1d4340c, [Ljava.lang.Object;@a51027, [Ljava.lang.Object;@c7833c, [Ljava.lang.Object;@790192, [Ljava.lang.Object;@5646a5, [Ljava.lang.Object;@381a9c, [Ljava.lang.Object;@15b011c], version=1, hitCount=0, CreationTime = 1347457596485, LastAccessTime = 1347457596485 ]> 
<RELOADING CACHE> 
<enter - get all parameters> 
... 

正如你所看到的,调用getParemeters触发溢出事件,然后调用getAllParameter来刷新缓存,但此调用会重新触发已过期的事件...因此刷新缓存的过程将执行两次!

在此先感谢您的帮助。

回答

1

您可以移动代码以将数据重新加载到另一个方法(在另一个bean中),并使用spring @Async注释异步执行。

这种方式回调将返回并且ehcache将从缓存中移除条目(希望在异步调用被触发之前)。

在条目被移除之前,仍然有可能发生异步,在这种情况下,您可能会收到对监听器的重复调用 - 但这很少见。

+0

谢谢,会尽力回复你 – Cygnusx1