I'm not sure whether it is problem of cache, hibernate or my design. Please 
give me an advise if there's a well-known pattern to solve this.

Suppose I have an entity with two props - key and value mapped to a table with 
two fields.


  | <hibernate-mapping>
  |     <class name="test.TestEntity" table="TEST_ENTITY">
  |         <cache usage="transactional"/>
  | 
  |         <id name="id" type="int" >
  |             <generator class="assigned"/>
  |         </id>
  | 
  |         <property name="value" type="int"/>
  |     </class>
  | </hibernate-mapping>
  | 
  | 

Suppose I have a servlet which prints values for keys passed as parameter. 
(like /servletName?keyList=1,2,3,4)

Servlet looks like 


  |     void service(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
  | 
  |         StringTokenizer st = new 
StringTokenizer(request.getParameter("keyList"), ",");
  |         UserTransaction utx;
  |         try {
  |             utx = (UserTransaction)new 
InitialContext().lookup("UserTransaction");
  |             utx.begin();
  | 
  |             Session session = 
HibernateContext.getSession("java:/hibernate/SessionFactory");
  | 
  |             while(st.hasMoreTokens()){
  |                 Integer id = new Integer(st.nextToken());
  | 
  |                 System.out.println(""+Thread.currentThread()+" loading 
"+id);
  |                 session.load(TestEntity.class, id);
  |                 Thread.sleep(1000);
  |             }
  | 
  |             utx.commit();
  |         } catch (Exception e) {
  |             e.printStackTrace();
  |         }
  | 
  | 
  | 
  | }
  | 
  | 


If I request simultaneously following url's:

..../servletName?keyList=1,2,3,4,5,6,7,8,9,10
and
..../servletName?keyList=10,9,8,7,6,5,4,3,2,1

I hava 100% chance to get a deadlock.

anonymous wrote : 
  | 20:06:29,588 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 1
  | 20:06:31,635 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor24,5,jboss] 
loading 10
  | 20:06:37,807 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 2
  | 20:06:39,041 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 3
  | 20:06:40,197 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 4
  | 20:06:41,619 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 5
  | 20:06:42,760 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 6
  | 20:06:43,057 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor24,5,jboss] 
loading 9
  | 20:06:43,901 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 7
  | 20:06:44,229 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor24,5,jboss] 
loading 8
  | 20:06:45,119 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor25,5,jboss] 
loading 8
  | 20:06:45,401 INFO  [STDOUT] Thread[http-0.0.0.0-8180-Processor24,5,jboss] 
loading 7
  | 20:07:00,135 ERROR [IdentityLock] read lock for 
//hibernate/test/TestEntity/8 could not be acquired after 15000 ms. Lock
  | map ownership Read lock owners: []
  | Write lock owner: :2
  |  (caller=:1)
  | 20:07:00,166 INFO  [STDOUT] net.sf.hibernate.cache.CacheException: 
org.jboss.cache.lock.TimeoutException: lock for //hibe
  | rnate/test/TestEntity/8 could not be acquired after 15000ms. Lock map 
ownership  Read lock owners: []
  | Write lock owner: :2
  | 
  |         at net.sf.hibernate.cache.TreeCache.get(TreeCache.java:61)
  |         at 
net.sf.hibernate.cache.TransactionalCache.get(TransactionalCache.java:29)
  |         at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2121)
  |         at 
net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:2000)
  |         at net.sf.hibernate.impl.SessionImpl.load(SessionImpl.java:1929)
  |         at test.TestCacheLockServlet.service(TestCacheLockServlet.java:57)
  |         at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
  |         at 
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:75)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
  |         at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
  |         at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:66)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:162)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:535)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
  |         at 
org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
  |         at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
  |         at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
  |         at 
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
  |         at 
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
  |         at java.lang.Thread.run(Thread.java:595)
  | Caused by: org.jboss.cache.lock.TimeoutException: lock for 
//hibernate/test/TestEntity/8 could not be acquired after 1500
  | 0ms. Lock map ownership  Read lock owners: []
  | Write lock owner: :2
  | 
  |         at 
org.jboss.cache.lock.IdentityLock.acquireReadLock(IdentityLock.java:218)
  |         at org.jboss.cache.Node.acquireReadLock(Node.java:418)
  |         at org.jboss.cache.Node.acquire(Node.java:399)
  |         at 
org.jboss.cache.interceptors.LockInterceptor.lock(LockInterceptor.java:202)
  |         at 
org.jboss.cache.interceptors.LockInterceptor.invoke(LockInterceptor.java:144)
  |         at 
org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:40)
  |         at 
org.jboss.cache.interceptors.CreateIfNotExistsInterceptor.invoke(CreateIfNotExistsInterceptor.java:50)
  |         at 
org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:40)
  |         at 
org.jboss.cache.interceptors.UnlockInterceptor.invoke(UnlockInterceptor.java:35)
  |         at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:2978)
  |         at org.jboss.cache.TreeCache.get(TreeCache.java:1509)
  |         at org.jboss.cache.TreeCache.get(TreeCache.java:1493)
  |         at net.sf.hibernate.cache.TreeCache.get(TreeCache.java:58)
  |         ... 39 more
  | 20:07:00,401 ERROR [IdentityLock] read lock for 
//hibernate/test/TestEntity/7 could not be acquired after 15000 ms. Lock
  | map ownership Read lock owners: []
  | Write lock owner: :1
  |  (caller=:2)
  | 20:07:00,416 INFO  [STDOUT] net.sf.hibernate.cache.CacheException: 
org.jboss.cache.lock.TimeoutException: lock for //hibe
  | rnate/test/TestEntity/7 could not be acquired after 15000ms. Lock map 
ownership  Read lock owners: []
  | Write lock owner: :1
  | 
  |         at net.sf.hibernate.cache.TreeCache.get(TreeCache.java:61)
  |         at 
net.sf.hibernate.cache.TransactionalCache.get(TransactionalCache.java:29)
  |         at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2121)
  |         at 
net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:2000)
  |         at net.sf.hibernate.impl.SessionImpl.load(SessionImpl.java:1929)
  |         at test.TestCacheLockServlet.service(TestCacheLockServlet.java:57)
  |         at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
  |         at 
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:75)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
  |         at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
  |         at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
  |         at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:66)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:162)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:535)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
  |         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
  |         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
  |         at 
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
  |         at 
org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
  |         at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
  |         at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
  |         at 
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
  |         at 
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
  |         at java.lang.Thread.run(Thread.java:595)
  | Caused by: org.jboss.cache.lock.TimeoutException: lock for 
//hibernate/test/TestEntity/7 could not be acquired after 1500
  | 0ms. Lock map ownership  Read lock owners: []
  | Write lock owner: :1
  | 
  |         at 
org.jboss.cache.lock.IdentityLock.acquireReadLock(IdentityLock.java:218)
  |         at org.jboss.cache.Node.acquireReadLock(Node.java:418)
  |         at org.jboss.cache.Node.acquire(Node.java:399)
  |         at 
org.jboss.cache.interceptors.LockInterceptor.lock(LockInterceptor.java:202)
  |         at 
org.jboss.cache.interceptors.LockInterceptor.invoke(LockInterceptor.java:144)
  |         at 
org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:40)
  |         at 
org.jboss.cache.interceptors.CreateIfNotExistsInterceptor.invoke(CreateIfNotExistsInterceptor.java:50)
  |         at 
org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:40)
  |         at 
org.jboss.cache.interceptors.UnlockInterceptor.invoke(UnlockInterceptor.java:35)
  |         at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:2978)
  |         at org.jboss.cache.TreeCache.get(TreeCache.java:1509)
  |         at org.jboss.cache.TreeCache.get(TreeCache.java:1493)
  |         at net.sf.hibernate.cache.TreeCache.get(TreeCache.java:58)
  |         ... 39 more
  | 
  | 


The thing is: when I try to read an entity which is missing in cache it is 
loaded from storage and get written to cache leaving a write lock.
As soon as entities get evicted from cache, ANY "read" of entity can become 
"write" to cache requiring write lock. 

My question is: is it possible to avoid deadlocks when reading entities in 
random order (very common scenario).




View the original post : 
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3863790#3863790

Reply to the post : 
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3863790


-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
_______________________________________________
JBoss-Development mailing list
JBoss-Development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to