openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rick Curtis (JIRA)" <j...@apache.org>
Subject [jira] [Resolved] (OPENJPA-2472) Concurrency issue in ClassMetaData.getPkAndNonPersistentManagedFmdIndexes()
Date Wed, 05 Feb 2014 23:16:09 GMT

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

Rick Curtis resolved OPENJPA-2472.
----------------------------------

       Resolution: Fixed
    Fix Version/s: 2.4.0

Committed revision 1564989 to trunk. Thanks for the patch Dalia!

I'll note that I excluded your contributed test as recreating this timing window is very machine
dependent. 

> Concurrency issue in ClassMetaData.getPkAndNonPersistentManagedFmdIndexes()
> ---------------------------------------------------------------------------
>
>                 Key: OPENJPA-2472
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2472
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.2.2, 2.3.0
>            Reporter: Benjamin Bentmann
>            Assignee: Rick Curtis
>             Fix For: 2.4.0
>
>         Attachments: OPENJPA-2472.txt
>
>
> In a scenario where brand new entity instances of the same class get inserted concurrently,
we noticed sporadic failures like this:
> Caused by: <openjpa-2.3.0-r422266:1540826 fatal store error> org.apache.openjpa.persistence.EntityNotFoundException:
The transaction has been rolled back.  See the nested exceptions for details on the errors
that occurred.
> 	at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2370)
> 	at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2207)
> 	at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2105)
> 	at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2023)
> 	at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
> 	at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1528)
> 	at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:933)
> 	at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:570)
> 	... 2 more
> Caused by: <openjpa-2.3.0-r422266:1540826 nonfatal store error> org.apache.openjpa.persistence.EntityNotFoundException:
The instance of type "class ..." with oid "ec2cfaa9e2f04b628d7e1991e65751dc" no longer exists
in the data store.  This may mean that you deleted the instance in a separate transaction,
but this context still has a cached version.
> 	at org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3109)
> 	at org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3188)
> 	at org.apache.openjpa.kernel.StateManagerImpl.fetchStringField(StateManagerImpl.java:2474)
> 	at org.apache.openjpa.kernel.StateManagerImpl.fetchString(StateManagerImpl.java:2464)
> 	at org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy.insert(StringFieldStrategy.java:105)
> 	at org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:623)
> 	at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:238)
> 	at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:165)
> 	at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:96)
> 	at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:77)
> 	at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:732)
> 	at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131)
> 	... 9 more
> The primary ID of each entity is set manually by the app prior to insertion.
> Debugging led me to ClassMetaData.getPkAndNonPersistentManagedFmdIndexes() which is called
from StateManagerImpl.initialize() to set up the _loaded bit set. When the above exception
occurs, all bits in that set are zero. This ultimately caused the erroneous loadField() call
that fails the insertion.
> The following line in getPkAndNonPersistentManagedFmdIndexes() disturbs the thread-safety:
> _pkAndNonPersistentManagedFmdIndexes = new int[idsSize];
> Once this has executed, another thread which executes the if (_pkAndNonPersistentManagedFmdIndexes
== null) in line 2778 can read the array before the first thread has finished the loop that
initializes its values.
> The line following "// Default to FALSE, until proven true." in hasPKFieldsFromAbstractClass()
looks equally troublesome, setting an instance variable to a temp value. Somebody whose more
familar with the codebase might want to check for more occurrences of this pattern.



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

Mime
View raw message