2016-08-29 1 views
1

Dans mon application, l'ehcache est configuré comme ci-dessous.Exception de modification simultanée d'Ehcache utilisant l'application + Spring + Struts

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”); 
} 
} 

configuration 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> 

// Il y a une couche de service pour l'application région de stockage de données.

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); 
} 
} 

Dans l'application, après le remplissage des données dans l'objet DTO j'appelle la méthode storeCustObjInCache() de la classe appDataStoreService pour écrire le contenu sur le disque.

L'ehcache est configuré comme singleton plutôt que comme instance.

L'application Web utilise des structures de structure (2.3.20) pour le flux Web et la structure Spring (4.1.2) pour la gestion des objets DI.

De même JSP pour UI, nous itérons l'objet bean use qui a une liste pour afficher le contenu.

Nous avons migré vers ehcache 2.9.0 à partir de la version 1.2.2 en modifiant simplement le fichier jar et la configuration dans le contexte printanier xml. Après la migration, nous avons commencé à obtenir l'exception ci-dessous fréquemment.

net.sf.ehcache.CacheException: Echec de la sérialisation de l'élément en raison de ConcurrentModificationException. Ceci est souvent le résultat d'un partage inapproprié d'un objet dangereux (par exemple ArrayList, HashMap, etc.) entre les threads sur net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement (DiskStorageFactory.java:405) sur net.sf. ehcache.store.disk.DiskStorageFactory.write (DiskStorageFactory.java:385) sur net.sf.ehcache.store.disk.DiskStorageFactory $ DiskWriteTask.call (DiskStorageFactory.java:477) sur net.sf.ehcache.store. disk.DiskStorageFactory $ PersistentDiskWriteTask.call (DiskStorageFactory.java:1071) at net.sf.ehcache.store.disk.DiskStorageFactory $ PersistentDiskWriteTask.call (DiskStorageFactory.java:1055) at java.util.concurrent.FutureTask.run (FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 201 (ScheduledThread PoolExecutor.java:180) à java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run (ScheduledThreadPoolExecutor.java:293) à java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142) à java.util. concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:617) at java.lang.Thread.run (Thread.java:745) Causé par: java.util.ConcurrentModificationException at java.util.ArrayList.writeObject (ArrayList .java: 766) à sun.reflect.GeneratedMethodAccessor8008.invoke (Source inconnue) à sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) à java.lang.reflect.Method.invoke (Method.java: 497) à java.io. ObjectStreamClass.invokeWriteObject (ObjectStreamClass.java:988) à java.io.ObjectOutputStream.writeSerialData (ObjectOutputStream.java:1496) à java.io.ObjectOutputStream.writeOrdinaryObject (ObjectOutputStream.java:1432) à 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. defaultWriteFields (ObjectOutputStream.java:1548) à java.io.ObjectOutputStream.defaultWriteObject (ObjectOutputStream.java:441) à net.sf.ehcache.Element.writeObject (Element.java:875)

Ma compréhension pourquoi cela se produit est, quand le ehcache essaye d'écrire au disque un autre thread modifie la liste sérialisée. Je ne pourrais pas trouver quel fil et la possibilité pour cela.

Existe-t-il un exemple sur la façon d'utiliser l'ehcache en utilisant ce type de programmation sans annotation au printemps.

Et une idée sur la façon d'identifier le fil qui cause ce problème

Répondre

2

Vous avez deux options:

  1. Trouve tous les chemins de code muter tout objet après avoir mises en cache, il
  2. Assurez-vous que ce que vous le cache est immuable

Je préférerais l'option 2 si vous pouvez refactoriser votre application de cette façon.

Ce problème n'est absolument pas dû à la façon dont vous câblez les différents objets participants, qui n'utilisent pas d'annotations dans l'exemple fourni.