jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jukka Zitting (JIRA)" <j...@apache.org>
Subject [jira] Updated: (JCR-2579) InvalidItemStateException when attempting concurrent, non conflicting writes
Date Fri, 16 Apr 2010 14:14:25 GMT

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

Jukka Zitting updated JCR-2579:
-------------------------------

    Fix Version/s: 2.1.1
                       (was: 2.1.0)

Unfortunately I still don't have a fix for this issue, even though I can fairly easily recreate
it with the ConcurrentNodeModificationTest class in jackrabbit-core.

Since this is the last bug open for 2.1.0 and the number of use cases it impacts is somewhat
limited I'm postponing it to 2.1.1 to avoid holding up the 2.1.0 release too much.

> 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
>            Reporter: Dan Diephouse
>            Assignee: Jukka Zitting
>             Fix For: 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.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message