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

Jukka Zitting updated JCR-2272:
-------------------------------

    Attachment: 0001-JCR-2272-Errors-during-concurrent-session-import-of-.patch

See revisions 1173578 and 1173579 for the changes required to prevent an 
unexpected exception from locking the entire cluster.

I digged deeper into this problem and I think I now have a pretty good idea of 
what goes wrong. When a session creates a node with an explicitly given UUID, 
it can be that the new transient NodeState gets created right after some other 
thread has persisted another node with the exact same UUID. In such a case the 
new NodeState doesn't necessarily receive notifications about the other node 
having been created and thus its status is still STATUS_NEW. 

The attached patch contains an initial patch that attempts to prevent such 
cases by explicitly checking the underlying persistence manager for duplicate 
ids once a new NodeState has already been connected to the state notification 
mechanism. This check is only done when a predefined UUID is used, so it 
shouldn't affect performance too badly, though I'll still need to check how the 
creation of the localState instance in NodeImpl.makePersistent() affects this 
assumption (since there the id of a transient node gets copied).

The patch passes all tests and as far as I can tell fixes also the 
ConcurrentImportTest. However, it's a pretty complex change, so code reviews 
would be welcome.

> Errors during concurrent session import of nodes with same UUIDs
> ----------------------------------------------------------------
>
>                 Key: JCR-2272
>                 URL: https://issues.apache.org/jira/browse/JCR-2272
>             Project: Jackrabbit Content Repository
>          Issue Type: Bug
>          Components: jackrabbit-core, xml
>    Affects Versions: 2.0-alpha8
>            Reporter: Tobias Bocanegra
>         Attachments: 
> 0001-JCR-2272-Errors-during-concurrent-session-import-of-.patch, 2272.patch, 
> JCR-2272.patch, JCR-2272_NPE.patch, 
> JCR-2272__Errors_during_concurrent_session_import_of_nodes_with_same_UUIDs.patch,
>  JCR-2272_revised.patch, JCR2272.Sep12.patch, JCR2272.Sep13.patch, 
> JCR2272.Sep13b.patch, JCR2272.Sep15.patch, JCR2272.Sep6.patch, t4.html, 
> t4.txt, t5.txt
>
>
> 21.08.2009 16:22:14 *ERROR* [Executor 0] ConnectionRecoveryManager: could not 
> execute statement, reason: The statement was aborted because it would have 
> caused a duplicate key value in a unique or primary key constraint or unique 
> index identified by 'SQL090821042140130' defined on 'DEFAULT_BUNDLE'., 
> state/code: 23505/20000 (ConnectionRecoveryManager.java, line 453)
> 21.08.2009 16:22:14 *ERROR* [Executor 0] BundleDbPersistenceManager: failed 
> to write bundle: 6c292772-349e-42b3-8255-7729615c67de 
> (BundleDbPersistenceManager.java, line 1212)
> ERROR 23505: The statement was aborted because it would have caused a 
> duplicate key value in a unique or primary key constraint or unique index 
> identified by 'SQL090821042140130' defined on 'DEFAULT_BUNDLE'.
>       at org.apache.derby.iapi.error.StandardException.newException(Unknown 
> Source)
>       at 
> org.apache.derby.impl.sql.execute.IndexChanger.insertAndCheckDups(Unknown 
> Source)
>       at org.apache.derby.impl.sql.execute.IndexChanger.doInsert(Unknown 
> Source)
>       at org.apache.derby.impl.sql.execute.IndexChanger.insert(Unknown Source)
>       at org.apache.derby.impl.sql.execute.IndexSetChanger.insert(Unknown 
> Source)
>       at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(Unknown 
> Source)
>       at 
> org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown 
> Source)
>       at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown 
> Source)
>       at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown 
> Source)
>       at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown 
> Source)
>       at 
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown 
> Source)
>       at org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(Unknown 
> Source)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmtInternal(ConnectionRecoveryManager.java:371)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmtInternal(ConnectionRecoveryManager.java:298)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:261)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:239)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.BundleDbPersistenceManager.storeBundle(BundleDbPersistenceManager.java:1209)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.AbstractBundlePersistenceManager.putBundle(AbstractBundlePersistenceManager.java:709)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.AbstractBundlePersistenceManager.storeInternal(AbstractBundlePersistenceManager.java:651)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.AbstractBundlePersistenceManager.store(AbstractBundlePersistenceManager.java:527)
>       at 
> org.apache.jackrabbit.core.persistence.bundle.BundleDbPersistenceManager.store(BundleDbPersistenceManager.java:563)
>       at 
> org.apache.jackrabbit.core.state.SharedItemStateManager$Update.end(SharedItemStateManager.java:724)
>       at 
> org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1101)
>       at 
> org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:351)
>       at 
> org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
>       at 
> org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:326)
>       at 
> org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:326)
>       at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1098)
>       at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:925)
>       at 
> org.apache.jackrabbit.core.ConcurrentImportTest$1.execute(ConcurrentImportTest.java:73)
>       at 
> org.apache.jackrabbit.core.AbstractConcurrencyTest$Executor.run(AbstractConcurrencyTest.java:209)
>       at java.lang.Thread.run(Thread.java:637)

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to