`
kingquake21
  • 浏览: 262044 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

多线程下Hibernate出现死循环

 
阅读更多

HashMap在多线程下导致死循环的原因可以参考http://mailinator.blogspot.com/2009/06/beautiful-race-condition.html

在多线程环境下,各个线程的Hibernate Session不同,使用Hibernate查询一个实体时,非常罕见的出现了一次,堆栈如下

"pool-130-thread-6" prio=10 tid=0x00002aab010ed800 nid=0x3aba runnable [0x000000004addf000]
   java.lang.Thread.State: RUNNABLE
        at java.util.HashMap.put(HashMap.java:391)
        at org.hibernate.engine.StatefulPersistenceContext.addCollection(StatefulPersistenceContext.java:764)
        at org.hibernate.engine.StatefulPersistenceContext.addUninitializedCollection(StatefulPersistenceContext.java:733)
        at org.hibernate.type.CollectionType.getCollection(CollectionType.java:609)
        at org.hibernate.type.CollectionType.resolveKey(CollectionType.java:408)
        at org.hibernate.type.CollectionType.resolve(CollectionType.java:402)
        at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:120)
        at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:854)
        at org.hibernate.loader.Loader.doQuery(Loader.java:729)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
        at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
        at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3049)
        at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:399)
        at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
        at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
        at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:98)
        at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
        at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:836)
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:66)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
        at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150

   

 跟踪调试,发现在多个线程中确实存在相同的session,这些session存在于持久化实体中的CGLIB代理里面

由于这些实体对象是在进入多线程环境之前就已经查询出来了,但是他们关联的对象都是lazy-load,所以都以CGLIB的形式存在与这些实体对象中。于是,在多线程环境下,尽管重新生成了新的session,但是通过实体延迟加载时就会使用之前的session,这样就导致了一个错误的用法:并发使用Hibernate的session

 

分享到:
评论
1 楼 a14400610 2014-12-29  
我现在也碰到这个问题 请问有什么解决方法吗

相关推荐

Global site tag (gtag.js) - Google Analytics