使用+ Spring + Struts应用程序的Ehcache并发修改异常 [英] Ehcache concurrent modification exception using + Spring + Struts application

查看:175
本文介绍了使用+ Spring + Struts应用程序的Ehcache并发修改异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,ehcache的配置如下。

In my application the ehcache is configured as below.

AppDataRegion.java

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>

///应用数据存储区有一个服务层地区。

//There is a service layer for the app data store region.

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()方法将内容写入磁盘。

Within the application after populating the data in the DTO object I call the storeCustObjInCache() method of appDataStoreService class to write the content to disk.

将ehcache配置为单例而不是实例。

The ehcache is configured as singleton rather than instance.

Web应用程序使用Struts(2.3.20)框架进行Web流,使用Spring框架(4.1.2)进行DI对象管理。

The web application uses struts (2.3.20) framework for web flow and Spring framework (4.1.2) for DI object management.

也JSP for UI我们迭代了使用bean对象,该对象具有用于显示内容的列表。

Also JSP for UI we iterate the use bean object which has list to display contents.

我们从1.2.2迁移到ehcache 2.9.0,只是在春季改变了jar和配置xml上下文。迁移之后,我们开始经常收到以下异常。

We migrated to ehcache 2.9.0 from 1.2.2 just changing the jar and configuration in spring xml context. After the migration we started getting the below exception frequently.


net.sf.ehcache.CacheException:由于ConcurrentModificationException,未能序列化元素。这通常是由于net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:405)$ b $之间的线程
之间不适当地共享线程不安全对象(例如ArrayList,HashMap等)导致的。 b在net.sf.ehcache.store.disk.DiskStorageFactory.write(DiskStorageFactory.java:385)
在net.sf.ehcache.store.disk.DiskStorageFactory $ DiskWriteTask.call(DiskStorageFactory.java:477)$ net.sf.ehcache.store.disk.DiskStorageFactory $ PersistentDiskWriteTask.call(DiskStorageFactory.java:1071)上的b $ b net.sf.ehcache.store.disk.DiskStorageFactory $ PersistentDiskWriteTask.call(DiskStorageFactory.java :1055)java.util.concurrent.FutureTask.run(FutureTask.java:266)中的
java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 201(ScheduledThreadPoolExecutor.java:180)
at 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)
$ b在java.lang.Thread.run(Thread.java:745)
原因:java.util.ConcurrentModificationException
在java.util.ArrayList.writeObject(ArrayList.java:766)
在sun.reflect.GeneratedMethodAccessor8008.invoke(未知源)
在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)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
在java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
在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. net.sf.ehcache.Element.writeObject(Element.java:875)上的ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441)

net.sf.ehcache.CacheException: Failed to serialize element due to ConcurrentModificationException. This is frequently the result of inappropriately sharing thread unsafe object (eg. ArrayList, HashMap, etc) between threads at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:405) at net.sf.ehcache.store.disk.DiskStorageFactory.write(DiskStorageFactory.java:385) at net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask.call(DiskStorageFactory.java:477) at 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(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.util.ConcurrentModificationException at java.util.ArrayList.writeObject(ArrayList.java:766) at sun.reflect.GeneratedMethodAccessor8008.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(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) 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.defaultWriteObject(ObjectOutputStream.java:441) at net.sf.ehcache.Element.writeObject(Element.java:875)

我理解为什么会这样,当ehcache试图向磁盘写入数据时,另一个线程正在修改序列化列表。我找不到哪个线程以及它的可能性。

My understanding why this happens is, when the ehcache is trying to write to the disk another thread is modifying the serialized list.I couldn't find out which thread and the possibility for it.

是否有一个示例,说明如何在春季之内以编程方式使用ehcache而无需注释。

Is there an example on how to use the ehcache using programmatically like this without annotation within spring.

关于如何识别导致此问题的线程

And any insight on how to identify the thread that causing this issue

推荐答案

您有两个选择:


  1. 查找所有在缓存对象后将其突变的代码路径

  2. 确保缓存的内容是不变的

如果您能以这种方式重构应用程序,我会选择选项2。

I would favour option 2 if you can refactor your application that way.

此问题绝对不是由连接不同的参与者对象的方式,顺便说一下,在提供的示例中它不使用注释。

This problem is absolutely not caused by the way you wire the different participant objects, which by the way does not use annotations in the example provided.

这篇关于使用+ Spring + Struts应用程序的Ehcache并发修改异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆