2

私のプロジェクトでは、ビジネス サービスのニーズに合わせて SQL DB のデータをキャッシュに保持する必要があります。これらのデータは、管理アプリで変更できるシステム パラメータのようなものです。

仕様によると、これらのデータの一部は 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>

このキャッシュが期限切れになると、私のリスナー通知メソッドが呼び出されます..いいですね。しかし、Docから。ehcacheの、notifyメソッドが戻るまでブロックを削除することを読みました!!!! この通知メソッドを使用して、DB をコールバックし、データをキャッシュにリロードしたかったのです。

この動作を 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 が呼び出されてキャッシュが更新されますが、この呼び出しによって期限切れのイベントが再度トリガーされます...したがって、キャッシュを更新するプロセスは 2 回行われます!!!

助けてくれてありがとう。

4

1 に答える 1

1

コードを移動してデータをキャッシュにリロードし、別のメソッド (別の Bean 内) に入れ、Spring @Async アノテーションを使用して非同期的に実行できます。

このようにして、コールバックが返され、ehcache がキャッシュからエントリを削除します (できれば、非同期呼び出しがトリガーされる前に)。

エントリが削除される前に非同期が発生する可能性はまだあります。その場合、リスナーへの呼び出しが重複する可能性がありますが、それはまれです。

于 2012-09-12T15:30:30.483 に答える