You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by "Adam Cooney (JIRA)" <ji...@apache.org> on 2010/07/29 10:54:17 UTC
[jira] Commented: (JCR-2579) InvalidItemStateException when
attempting concurrent, non conflicting writes
[ https://issues.apache.org/jira/browse/JCR-2579?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12893557#action_12893557 ]
Adam Cooney commented on JCR-2579:
----------------------------------
I can't see that the linked subversion commits fix in v1.6.3.
> InvalidItemStateException when attempting concurrent, non conflicting writes
> ----------------------------------------------------------------------------
>
> Key: JCR-2579
> URL: https://issues.apache.org/jira/browse/JCR-2579
> Project: Jackrabbit Content Repository
> Issue Type: Bug
> Components: jackrabbit-core
> Affects Versions: 1.6.1, 2.0.0, 2.1.0
> Reporter: Dan Diephouse
> Assignee: Jukka Zitting
> Fix For: 1.6.3, 2.0.2, 2.1.1
>
>
> I'm having some problems doing concurrent addition of nodes to a parent node in Jackrabbit. I've attached a simple test which starts up a bunch of threads which add nodes to a parent node concurrently. If I add in locks I can get this to work, however according to the mailing list this should work without locks. However, the test always fails with this:
> javax.jcr.InvalidItemStateException: Item cannot be saved because it has been modified externally: node /testParent
> at org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:281)
> at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:939)
> at org.mule.galaxy.impl.JackrabbitConcurrentWriteTest$1.run(JackrabbitConcurrentWriteTest.java:71)
> I'm using Jackrabbit 1.6.1. Here is my (verbose) node type:
> <nodeType name="galaxy:noSiblings"
> isMixin="false"
> hasOrderableChildNodes="false"
> primaryItemName="">
> <propertyDefinition name="*" requiredType="undefined" onParentVersion="COPY" />
> <propertyDefinition name="*" requiredType="undefined" onParentVersion="COPY" multiple="true"/>
> <childNodeDefinition name="*" defaultPrimaryType="nt:unstructured" onParentVersion="COPY" sameNameSiblings="false" />
> <supertypes>
> <supertype>nt:base</supertype>
> <supertype>mix:referenceable</supertype>
> <supertype>mix:lockable</supertype>
> </supertypes>
> </nodeType>
> And my test:
> package org.mule.galaxy.impl;
> import java.io.File;
> import java.io.IOException;
> import java.io.InputStream;
> import java.util.ArrayList;
> import java.util.List;
> import java.util.UUID;
> import java.util.concurrent.CountDownLatch;
> import java.util.concurrent.TimeUnit;
> import javax.jcr.LoginException;
> import javax.jcr.Node;
> import javax.jcr.Repository;
> import javax.jcr.RepositoryException;
> import javax.jcr.Session;
> import javax.jcr.SimpleCredentials;
> import junit.framework.TestCase;
> import org.apache.commons.io.FileUtils;
> import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
> import org.apache.jackrabbit.core.RepositoryImpl;
> import org.apache.jackrabbit.core.TransientRepository;
> import org.apache.jackrabbit.core.config.RepositoryConfig;
> public class JackrabbitConcurrentWriteTest extends TestCase {
>
> private Repository repository;
> private Session session;
> private String parentUUID;
> private boolean continueLoop = true;
>
> public void setUp() throws Exception {
> FileUtils.deleteDirectory(new File("repository"));
> File repoDir = new File("repository");
> repoDir.mkdirs();
> RepositoryConfig config = RepositoryConfig.create(new File("src/test/resources/META-INF/jackrabbit-repo-test.xml"), repoDir);
> repository = RepositoryImpl.create(config);
> session = createSession();
>
> createCustomNodeTypes(session);
>
> parentUUID = session.getRootNode().addNode("testParent", "galaxy:noSiblings").getUUID();
> session.save();
> session.logout();
> }
> private Session createSession() throws LoginException, RepositoryException {
> return repository.login(new SimpleCredentials("username", "password".toCharArray()));
> }
>
> public void testConcurrency() throws Exception {
> final List<Exception> exceptions = new ArrayList<Exception>();
> int threadCount = 20;
> final CountDownLatch latch = new CountDownLatch(threadCount);
>
> for (int i = 0; i < threadCount; i++) {
> Thread thread = new Thread() {
> @Override
> public void run() {
> try {
> while (continueLoop) {
> Session session = createSession();
> try {
> Node node = session.getNodeByUUID(parentUUID);
> node.addNode(UUID.randomUUID().toString());
> node.save();
> session.save();
> } finally {
> session.logout();
> }
> }
> } catch (RepositoryException e) {
> exceptions.add(e);
> continueLoop = false;
> }
> latch.countDown();
> }
>
> };
> thread.start();
> }
>
> latch.await(10, TimeUnit.SECONDS);
> continueLoop = false;
>
> for (Exception e : exceptions) {
> e.printStackTrace();
> }
> assertEquals(0, exceptions.size());
> }
>
> public void createCustomNodeTypes(Session session) throws RepositoryException, IOException {
> // Get the JackrabbitNodeTypeManager from the Workspace.
> // Note that it must be cast from the generic JCR NodeTypeManager to
> // the Jackrabbit-specific implementation.
> // (see: http://jackrabbit.apache.org/node-types.html)
> JackrabbitNodeTypeManager manager = (JackrabbitNodeTypeManager) session.getWorkspace().getNodeTypeManager();
> // Register the custom node types defined in the CND file
> InputStream is = Thread.currentThread().getContextClassLoader()
> .getResourceAsStream("org/mule/galaxy/impl/jcr/nodeTypes.xml");
> manager.registerNodeTypes(is, JackrabbitNodeTypeManager.TEXT_XML);
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.