[
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