【问题标题】:Eclipselink throwing ConcurrentModificationExceptionEclipselink 抛出 ConcurrentModificationException
【发布时间】:2013-08-09 10:59:36
【问题描述】:

我在应用程序代码中遇到了一些ConcurrentModificationException 的问题:

   Caused by: Exception [EclipseLink-2004] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.ConcurrencyException
Exception Description: A signal was attempted before wait() on ConcurrencyManager. This normally means that an attempt was made to 
commit or rollback a transaction before it was started, or to rollback a transaction twice.
        at org.eclipse.persistence.exceptions.ConcurrencyException.signalAttemptedBeforeWait(ConcurrencyException.java:84)
        at org.eclipse.persistence.internal.helper.ConcurrencyManager.releaseReadLock(ConcurrencyManager.java:489)
        at org.eclipse.persistence.internal.identitymaps.CacheKey.releaseReadLock(CacheKey.java:392)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:1022)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:933)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(UnitOfWorkIdentityMapAccessor.java:197)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:125)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3920)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3874)
        at org.eclipse.persistence.mappings.ObjectReferenceMapping.buildUnitofWorkCloneForPartObject(ObjectReferenceMapping.java:109)
        at org.eclipse.persistence.mappings.ObjectReferenceMapping.buildCloneForPartObject(ObjectReferenceMapping.java:71)
        at org.eclipse.persistence.internal.indirection.UnitOfWorkQueryValueHolder.buildCloneFor(UnitOfWorkQueryValueHolder.java:56)
        at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:161)
        at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:222)
        at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:88)

分析代码,我发现负责提供 EntityManager 的类:

import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import weblogic.javaee.CallByReference;

@Stateful (name = "DAOFactoryRemoteBean", mappedName = "DAOFactoryRemoteBean")
@CallByReference
public class DAOFactoryRemoteImplBean implements DAOFactoryRemoteBean {

    @PersistenceContext(unitName = "server_unit")
    private EntityManager em;

    private static String getDAOName(Class<?> classeEntidade) {
        String result = classeEntidade.getName()
            .replace("org.networkmap.server.bean.",
            "org.networkmap.server.bean.dao.");
        result = result.concat("DAO");
        return result;
    }

    @Override
    public Object getDAO(Class<?> entityClass) {
        NetworkmapDao result = null;

        try {
           result = (NetworkmapDao) Class.forName(getDAOName(entityClass))
               .newInstance();
           result.setEntityManager(em);
        } catch (Exception e) {
           e.printStackTrace();
        }
        return result;
    }
}

有很多 EJB 调用 getDAO 方法。还有很多应用程序的用户。我想这可能确实会导致并发问题。

我对此没有很好的专业知识,但根据互联网上的一些搜索,考虑到EntityManger 不是线程安全的,似乎该代码没有好的做法。我被这个问题困住了:(

该应用程序使用 EclipseLink v2.4.2 API,在 Solaris OS 上的 Weblogic 10.3.5 上运行。在persistence.xml 上只声明了一个持久性单元。

请有人帮助我。

【问题讨论】:

  • 此处相关的代码路径是 EJB 的特定入口点(某些方法),以及该方法如何直接和间接访问事务管理器(提示:不应该)&实体经理。还有足够的堆栈跟踪来识别代码中实际触发异常的点(大概它会在已经讨论过的代码路径上)。这里没有提供这些。

标签: java jpa ejb entitymanager


【解决方案1】:

您是否在不同线程中使用相同的 EntityManager?如果是这样,那就不要那样做。

否则,请包含完整的异常堆栈跟踪。

什么意思,“result.setEntityManager(em);”怎么办?

【讨论】:

  • NetworkmapDao 是所有 DAO 扩展的抽象类。 setEntityManager(em) 为每个 DAO 设置对实体管理器的引用。那么对于有很多线程的情况,最好的方法是什么?
猜你喜欢
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2017-10-18
  • 1970-01-01
相关资源
最近更新 更多