openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hiroki Tateno (JIRA)" <j...@apache.org>
Subject [jira] Updated: (OPENJPA-913) A deadlock issue happens when DirtyListener is used
Date Mon, 09 Feb 2009 06:59:02 GMT

     [ https://issues.apache.org/jira/browse/OPENJPA-913?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Hiroki Tateno updated OPENJPA-913:
----------------------------------

    Attachment: proposed-fix.patch

Also, I attached possible fix of the issue.
The root cause of the issue is sometimes BrokerImpl.fireLifecycleEvent
is called without BrokerImpl lock. So, I added lock()/unlock() to 
BrokerImpl.fireLifecycleEvent. It may be overkill fix. If it's overkill,
it's better that adding broker.lock()/broker.unlock() to around
calling fireLifecycleEvent() in StateManagerImpl.dirty().


> A deadlock issue happens when DirtyListener is used
> ---------------------------------------------------
>
>                 Key: OPENJPA-913
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-913
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 1.2.0
>         Environment: Linux x86
>            Reporter: Hiroki Tateno
>         Attachments: proposed-fix.patch, testcase.zip
>
>
> A deadlock issue happens when OpenJPA entity manager is
> concurrently called and DirtyListener is used and 
> DirtyListener.beforeDirty calls an entity manager related 
> operation. To call OpenJPA entity manager concurrently, 
> we need to define openjpa.MulthThreaded option as true.
> Following is test scenario.
> 1. Thread A calls entityMangaer.refresh() repeatedly.
>    In refresh() method, entityManager acquires BrokerImpl
>    lock. And then, entityManager acquires LifecycleEventManager
>    lock to call lifecycle callback.
> 2. Thread B calls persistedObject.getAItems() (getting
>    collection items).
> 3. In enhanced getItems() method, entityManager tries
>    to mark it as "dirty". Before marking, callback listener
>    DirtyListener.beforeDirty is called. In this point,
>    LifecycleEventManager lock is acquired without acquiring
>    BrokerImpl lock.
> 4. In the testcase, beforeDirty calls persistedObject.getAItems().
>    And then, entity manager tries to acquire BrokerImpl lock.
>    But, sometimes BrokerImpl lock is already acquired by Thread B.
>    So, a deadlock issue happens. deadlock stack is as follows.
> ====
>      [java] "Thread-1" prio=1 tid=0x09e98b28 nid=0x7fcc waiting on condition [0xb15f3000..0xb15f4130]
>      [java]     at sun.misc.Unsafe.park(Native Method)
>      [java]     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
>      [java]     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)
>      [java]     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)
>      [java]     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)
>      [java]     at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)
>      [java]     at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.lock(BrokerImpl.java:4168)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.beginOperation(BrokerImpl.java:1770)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.isActive(BrokerImpl.java:1742)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.beforeRead(StateManagerImpl.java:964)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1501)
>      [java]     at model.A.getAItems(A.java)
>      [java]     at model.ADirtyListener.beforeDirty(ADirtyListener.java:24)
>      [java]     at org.apache.openjpa.event.LifecycleEventManager.fireEvent(LifecycleEventManager.java:423)
>      [java]     at org.apache.openjpa.event.LifecycleEventManager.fireEvent(LifecycleEventManager.java:289)
>      [java]     - locked <0x51b4e4b0> (a org.apache.openjpa.event.LifecycleEventManager)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.fireLifecycleEvent(BrokerImpl.java:693)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.fireLifecycleEvent(StateManagerImpl.java:364)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.dirty(StateManagerImpl.java:1596)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.dirty(StateManagerImpl.java:1539)
>      [java]     at org.apache.openjpa.util.Proxies.dirty(Proxies.java:66)
>      [java]     at org.apache.openjpa.util.ProxyCollections.beforeAdd(ProxyCollections.java:57)
>      [java]     at org.apache.openjpa.util.java$util$HashSet$proxy.add(Unknown Source)
>      [java]     at business.Test$2.run(Test.java:80)
>      [java]     at java.lang.Thread.run(Thread.java:595)
>      [java] "Thread-0" prio=1 tid=0x09e9d010 nid=0x7fcb waiting for monitor entry [0xb1674000..0xb1674db0]
>      [java]     at org.apache.openjpa.event.LifecycleEventManager.fireEvent(LifecycleEventManager.java:272)
>      [java]     - waiting to lock <0x51b4e4b0> (a org.apache.openjpa.event.LifecycleEventManager)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.fireLifecycleEvent(BrokerImpl.java:693)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.fireLifecycleEvent(StateManagerImpl.java:364)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.clearFields(StateManagerImpl.java:2647)
>      [java]     at org.apache.openjpa.kernel.StateManagerImpl.beforeRefresh(StateManagerImpl.java:1239)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.refreshInternal(BrokerImpl.java:2835)
>      [java]     at org.apache.openjpa.kernel.BrokerImpl.refresh(BrokerImpl.java:2781)
>      [java]     at org.apache.openjpa.kernel.DelegatingBroker.refresh(DelegatingBroker.java:1078)
>      [java]     at org.apache.openjpa.persistence.EntityManagerImpl.refresh(EntityManagerImpl.java:694)
>      [java]     at business.Test$1.run(Test.java:64)
>      [java]     at java.lang.Thread.run(Thread.java:595)
> ====
> Intially the problem is reproduced on OpenJPA 1.x. But,
> I verified the problem could be reproduced with latest 
> OpenJPA head.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message