[ http://issues.apache.org/jira/browse/IBATIS-223?page=all ]

Sven Boden updated IBATIS-223:
------------------------------

    Attachment: CacheModel.java
                CachingStatement.java

Attached a replacement for a (simpler) CacheModel which shouldn't cause 
deadlocks. I tested it, it also doesn't break the iBATIS unit tests. But no 
further guarantees. I would like someone else than me to have a look at it.

CachingStatement needs to be changed because of the method getLock() which I 
removed. What I also haven't figured out in the original version is why in 
method CacheModel.getLock() an element is inserted in the HashMap lockMap, but 
why there is nothing there to clear lockMap. This would make lockMap huge when 
running iBATIS for a long time.

Regards,
Sven

> Thread deadlock due to CacheModel.flush()
> -----------------------------------------
>
>          Key: IBATIS-223
>          URL: http://issues.apache.org/jira/browse/IBATIS-223
>      Project: iBatis for Java
>         Type: Bug
>   Components: SQL Maps
>     Versions: 2.1.5
>  Environment: Redhat Linux ES 3.0 + Weblogic 8.1SP4+iBatis 2.1.5 + OSCache 
> 2.2 + JGroups 2.2.8
>     Reporter: Vincent Royer
>     Priority: Minor
>  Attachments: CacheModel.java, CachingStatement.java
>
> As shown by the following thread dump, a deadlock occurs between thead 7 and 
> 10. As the result, almost all theads were locked due to this deadlock. 
> It seems that thread 10 locks the [EMAIL PROTECTED] object in 
> CacheModel.getObject() then is locked on [EMAIL PROTECTED] in 
> CacheModel.flush(). In the same time, thread 7 locks [EMAIL PROTECTED] in 
> CachingStatement.executeQueryForList(), then is lock on [EMAIL PROTECTED]  
> when calling CacheModel.getLockKey() from CacheModel.putObject().
> Of course, such deadlock occur when 2 threads work with the same cached 
> object and when this object is often flushed.
> Thread-0xc00 "ExecuteThread: '10' for queue: 
> 'ExecutionAsynchroneThreadQueue'" <Active, priority=5, DAEMON> { 
>     java/util/HashMap.get(Ljava/lang/Object;)Ljava/lang/Object;(Optimized 
> Method) 
>     
> com/ibatis/sqlmap/engine/cache/CacheModel.getObject(Lcom/ibatis/sqlmap/engine/cache/CacheKey;)Ljava/lang/Object;(Optimized
>  Method) 
>     ^-- Holding lock: com/ibatis/sqlmap/engine/cache/[EMAIL PROTECTED] lock] 
>     
> com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.executeQueryForList(Lcom/ibatis/sqlmap/engine/scope/RequestScope;Lcom/ibatis/s
>  
> qlmap/engine/transaction/Transaction;Ljava/lang/Object;II)Ljava/util/List;(Optimized
>  Method) 
>     
> com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl.queryForList(Ljava/lang/String;Ljava/lang/Object;)Ljava/util/List;(Optimized
>  Method) 
>     
> cofidis/fwk/ancestor/DaoAncestor$3.executeSqlAction(Lcom/ibatis/sqlmap/client/SqlMapSession;)Ljava/lang/Object;(Optimized
>  Method) 
> .... 
> Thread-0xa80 "ExecuteThread: '7' for queue: 'ExecutionAsynchroneThreadQueue'" 
> <Active, priority=5, DAEMON> { 
>     -- Blocked trying to get lock: com/ibatis/sqlmap/engine/cache/[EMAIL 
> PROTECTED] lock] 
>     jrockit/vm/Threads.shortNap(I)V(Native Method) 
>     jrockit/vm/Locks.waitForThinRelease(Ljava/lang/Object;I)I(Optimized 
> Method) 
>     
> jrockit/vm/Locks.monitorEnterSecondStage(Ljava/lang/Object;I)Ljava/lang/Object;(Optimized
>  Method) 
>     
> jrockit/vm/Locks.monitorEnter(Ljava/lang/Object;)Ljava/lang/Object;(Native 
> Method) 
>     
> com/ibatis/sqlmap/engine/cache/CacheModel.getLock(Lcom/ibatis/sqlmap/engine/cache/CacheKey;)Ljava/lang/Object;(CacheModel.java:324)
>  
>     
> com/ibatis/sqlmap/engine/cache/CacheModel.putObject(Lcom/ibatis/sqlmap/engine/cache/CacheKey;Ljava/lang/Object;)V(CacheModel.java:313)
>  
>     
> com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.executeQueryForList(Lcom/ibatis/sqlmap/engine/scope/RequestScope;Lcom/ibatis/s
>  
> qlmap/engine/transaction/Transaction;Ljava/lang/Object;II)Ljava/util/List;(Optimized
>  Method) 
>     ^-- Holding lock: java/lang/[EMAIL PROTECTED] lock] 
>     
> com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl.queryForList(Ljava/lang/String;Ljava/lang/Object;)Ljava/util/List;(Optimized
>  Method) 
>     
> cofidis/fwk/ancestor/DaoAncestor$3.executeSqlAction(Lcom/ibatis/sqlmap/client/SqlMapSession;)Ljava/lang/Object;(Optimized
>  Method) 
>     
> cofidis/fwk/ancestor/DaoAncestor.execute(Lcofidis/fwk/ancestor/DaoAncestor$DaoCallback;)Ljava/lang/Object;(Optimized
>  Method) 
>     
> cofidis/fwk/ancestor/DaoAncestor.executeWithListResult(Lcofidis/fwk/ancestor/DaoAncestor$DaoCallback;)Ljava/util/List;(Optimized
>  Method) 
>     
> cofidis/fwk/ancestor/DaoAncestor.queryForList(Ljava/lang/String;Ljava/lang/Object;)Ljava/util/List;(Optimized
>  Method) 
> .... 
> Thread-0xa00 "ExecuteThread: '6' for queue: 'ExecutionAsynchroneThreadQueue'" 
> <Active, priority=5, DAEMON> { 
>     -- Blocked trying to get lock: com/ibatis/sqlmap/engine/cache/[EMAIL 
> PROTECTED] lock] 
>     jrockit/vm/Threads.shortNap(I)V(Native Method) 
>     jrockit/vm/Locks.waitForThinRelease(Ljava/lang/Object;I)I(Optimized 
> Method) 
>     
> jrockit/vm/Locks.monitorEnterSecondStage(Ljava/lang/Object;I)Ljava/lang/Object;(Optimized
>  Method) 
>     
> com/ibatis/sqlmap/engine/cache/CacheModel.getObject(Lcom/ibatis/sqlmap/engine/cache/CacheKey;)Ljava/lang/Object;(Optimized
>  Method) 
>     
> com/ibatis/sqlmap/engine/mapping/statement/CachingStatement.executeQueryForList(Lcom/ibatis/sqlmap/engine/scope/RequestScope;Lcom/ibatis/s
>  
> qlmap/engine/transaction/Transaction;Ljava/lang/Object;II)Ljava/util/List;(Optimized
>  Method)

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to