jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mat Lowery <mlow...@pentaho.com>
Subject Concurrent modifications to a single node
Date Thu, 22 Dec 2011 19:39:45 GMT
My understanding of concurrent modifications is that I can receive an 
InvalidItemStateException if I have a stale view of the repository when 
my session is saved or my transaction is committed.  However, I can get 
other exceptions using the code below.  Furthermore, I thought 
Jackrabbit would allow concurrent child node additions to a single node 
given the child node names were unique.  So I wasn't even expecting an 
InvalidItemStateException for the code below.

I understand that locking can prevent the InvalidItemStateException but 
I'm using transactions and committing the transaction for the sole 
purpose of exposing a lock is something I'd like to avoid at this time.  
I'd like to just catch the InvalidItemStateException and alert the user 
with a friendly message.

Why do I get the given exceptions for the given code?  I can supply full 
stacks if necessary; for now, just the class and error message are shown.

Jackrabbit 1.6.0:
* org.apache.jackrabbit.core.state.ItemStateException: there's already a 
property state instance with id 
243f6e39-7a3e-4d48-b051-9b4198a6a16b/{http://www.jcp.org/jcr/1.0}primaryType
* javax.jcr.InvalidItemStateException: Item cannot be saved because it 
has been modified externally: node /
* javax.jcr.InvalidItemStateException: node /: the node cannot be saved 
because it has been modified externally.

Jackrabbit 1.6.5:
* javax.jcr.InvalidItemStateException: node /: the node cannot be saved 
because it has been modified externally.
* javax.jcr.InvalidItemStateException: Item cannot be saved because it 
has been modified externally: node /
* org.apache.jackrabbit.core.state.ItemStateException: Child node entry 
with id 04afd8db-6515-4997-ac4e-83f066e39f53 has been removed, but is 
not present in the changelog

Jackrabbit 2.3.4:
* java.util.ConcurrentModificationException
     at java.util.WeakHashMap$HashIterator.nextEntry(WeakHashMap.java:762)
     at java.util.WeakHashMap$KeyIterator.next(WeakHashMap.java:795)
     at 
org.apache.jackrabbit.core.cache.CacheManager.logCacheStats(CacheManager.java:164)

package test;

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import org.apache.jackrabbit.core.TransientRepository;

public class JackrabbitTest {

   public static void main(final String[] args) throws Exception {
     File dir = File.createTempFile("jackrabbit-test", "");
     dir.delete();
     dir.mkdir();
     System.out.println("created temporary directory: " +
         dir.getAbsolutePath());
     dir.deleteOnExit();

     final Repository jcrRepo = new TransientRepository(dir);
     final AtomicBoolean passed = new AtomicBoolean(true);
     final AtomicInteger counter = new AtomicInteger(0);
     ExecutorService executor = Executors.newFixedThreadPool(50);
     Runnable runnable = new Runnable() {

       @Override
       public void run() {
         try {
           Session session = jcrRepo.login(
               new SimpleCredentials("admin",
                   "admin".toCharArray()));
           session.getRootNode().addNode("n" +
                   counter.getAndIncrement()); //unique name
           session.save();
           session.logout();
         } catch (RepositoryException e) {
           e.printStackTrace();
           passed.set(false);
         }
       }

     };
     System.out.println("Running threads");
     for (int i = 0; i < 500; i++) {
       executor.execute(runnable);
     }
     executor.shutdown(); //Disable new tasks from being submitted
     if (!executor.awaitTermination(120, TimeUnit.SECONDS)) {
       System.err.println("timeout");
       System.exit(1);
     }
     if (!passed.get()) {
       System.err.println("one or more threads got an exception");
       System.exit(1);
     } else {
       System.out.println("all threads ran with no exceptions");
       System.exit(0);
     }

   }

}


Mime
View raw message