2016-08-29 10 views
1

私のアプリケーションでは、ehcacheは以下のように構成されています。+ Spring + Strutsアプリケーションを使用したEhcache同時変更例外

AppDataRegion.java

//import statements. 

public class AppDataRegion{ 

//Variable for region identifier. 
private String appRegionId; 

// constructor sets the appRegionId; 
//obtained from the system current time. 
public AppDataRegion(){ 
appRegionId = String.valueOf(System.currentTimeMillis()); 
} 

//Variable for cachemanager 
// injected by spring DI from context xml 
Private CacheManager appCacheMngr; 

//necessary getter/setter methods for variable cachemanager 
//necessary getter/setter methods for variable appRegionId 

//method to create a region in cache using the appRegionId value 
private createRegion(){ 
    if (!appCacheMngr.cacheExists(appRegionId)){ 
    try { 
     appCacheMngr.addCache(appRegionId); 
    catch (exc){ 
    //exception handled 
    } 
    } 
} 

public Cache getRegion(){ 
if(appCacheMngr == null || !appCacheMngr.cacheExists(appRegionId)){ 
createRegion(); 
} 
return appCacheMangr.getCache(appRegionId); 
} 
private createCustRegion(){ 
    try{ 
    Cache custCache = appCacheMngr.getCache(“custdiskCache”); 
    If(null == custCache.addCache(custCache); 
    }catch (exp){ 
    //handled the exceptions 
} 
retrun appCacheMngr.getCache(“custdiskCache”); 
} 
} 

Spring構成

<bean id="appDataStoreService" class="com.app.cache.AppDataStoreService" >  
     <property name="appDataStoreRegion" ref="appDataStoreRegion"/> 
    </bean> 

    <bean id="appDataStoreRegion" class="com.app.cache.AppDataStoreRegion">   
     <property name="appcacheManager" ref="cacheManager"/> 
    </bean> 

<bean id="cacheManager" class="net.sf.ehcache.CacheManager" factory-method="create">  
     <constructor-arg index="0" type="java.net.URL" value="classpath:ehcache-app.xml" /> 
    </bean> 

//アプリのデータ記憶領域のためのサービス層があります。アプリケーション内

public class AppDataStoreService{ 

//datastoreregion variable declaration 
private AppDataStoreRegion appDataStoreRegion; 


public void storeCustObjInCache(String id, Object obj){ 
    Cache region = appDataStoreRegion.getCustRegion(); 
    If(region != null && id !=null && region.isElementInMemory(id)){ 
    region.remove(id); 
} 
Element ele = new Element(id, obj); 
If(region != null) region.put(ele); 
} 
} 

DTOオブジェクトにデータを移入した後、私は、ディスクにコンテンツを書き込むappDataStoreServiceクラスのstoreCustObjInCache()メソッドを呼び出します。

ehcacheは、インスタンスではなくシングルトンとして構成されています。

Webアプリケーションでは、Webフロー用のStruts(2.3.20)フレームワークとDIオブジェクト管理用のSpringフレームワーク(4.1.2)が使用されます。

また、UIのJSPでは、コンテンツを表示するリストを持つ使用Beanオブジェクトを反復処理します。

私たちは1.2.2からehcache 2.9.0に移行し、spring xmlコンテキストでjarと構成を変更しました。移行後、私たちは以下の例外を頻繁に取得し始めました。

net.sf.ehcache.CacheException:ConcurrentModificationExceptionのために要素をシリアル化できませんでした。これは頻繁に、スレッド間で不適切なスレッドのオブジェクト(ArrayList、HashMapなど)を不適切に共有した結果です。 at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:405) at net.sf. (ディスクストレージファクトリ。 disk.DiskStorageFactory $ PersistentDiskWriteTask.call(DiskStorageFactory.java:1071) at net.sf.ehcache.store.disk.DiskStorageFactory $ PersistentDiskWriteTask.call(DiskStorageFactory.java:1055) (java.util.concurrent.FutureTask.run) FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 201(ScheduledThread java.util.concurrent.ThreadPoolExecutor.runWorkerでjava.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) (ThreadPoolExecutor.java:1142)java.utilので でPoolExecutor.java:180) 。 (java.lang.Thread.run(Thread.java:745)) で発生しました:java.util.ConcurrentModificationException at java.util.ArrayList.writeObject(ArrayList .javaファイル:sun.reflect.DelegatingMethodAccessorImpl.invokeでsun.reflect.GeneratedMethodAccessor8008.invoke(不明なソース) で766) (java.lang.reflect.Method.invokeでDelegatingMethodAccessorImpl.java:43) (Method.java: 497) at java.io. ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream。 writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) のjava.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) のjava.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) のjava.io.ObjectOutputStreamです。 net.sf.ehcache.Element.writeObjectでjava.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441) でdefaultWriteFields(ObjectOutputStream.java:1548) (Element.java:875)

私の理解なぜこれが起こるのは、ehcacheがディスクに書き込もうとしているときに、別のスレッドがシリアル化されたリストを変更しているときです。私はどのスレッドとその可能性を見つけることができませんでした。

春に注釈なしでプログラムでこのようにehcacheを使用する方法の例がありますか?

そして、この問題

答えて

2

を引き起こしていることをスレッドを特定する方法上の任意の洞察次の2つのオプションがあります:あなたはそれをキャッシュされた後

  1. は必ず何を作る任意のオブジェクトを変異、すべてのコードパスを検索しますキャッシュが不変です

あなたのアプリケーションをそのようにリファクタリングすることができれば、私はオプション2が好きです。

この問題は、提供された例で注釈を使用していない別の参加者オブジェクトを配線する方法によっては絶対に発生していません。

関連する問題