jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mat Lowery <mlow...@pentaho.com>
Subject Re: Concurrent modifications to a single node
Date Fri, 23 Dec 2011 18:37:05 GMT
I had to run the test code on 2.3.4 many times before I got the 
ConcurrentModificationException.  I was not able to get a 
org.apache.jackrabbit.core.state.ItemStateException or 
javax.jcr.InvalidItemStateException on that version.

While I understand that the 1.6 branch is no longer maintained, I would 
like to be sure that I understand correct JCR behavior.  Is it a bug in 
1.6.x that the org.apache.jackrabbit.core.state.ItemStateExceptions are 
occurring or that they are being wrapped with a 
javax.jcr.RepositoryException rather than a 
javax.jcr.InvalidItemStateException?  A sample 1.6.5 full stack is:

javax.jcr.RepositoryException: Unable to update item: node /: Child node 
entry with id 04afd8db-6515-4997-ac4e-83f066e39f53 has been removed, but 
is not present in the changelog: Child node entry with id 
04afd8db-6515-4997-ac4e-83f066e39f53 has been removed, but is not 
present in the changelog
     at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1134)
     at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:915)
     at test.JackrabbitTest$1.run(JackrabbitTest.java:38)
     at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
     at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
     at java.lang.Thread.run(Thread.java:662)
Caused by: 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
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.validateModified(SharedItemStateManager.java:1383)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.validateHierarchy(SharedItemStateManager.java:1150)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.access$1100(SharedItemStateManager.java:116)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:717)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1473)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1503)
     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:1128)
     ... 5 more
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
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.validateModified(SharedItemStateManager.java:1383)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.validateHierarchy(SharedItemStateManager.java:1150)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.access$1100(SharedItemStateManager.java:116)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:717)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1473)
     at 
org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1503)
     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:1128)
     at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:915)
     at test.JackrabbitTest$1.run(JackrabbitTest.java:38)
     at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
     at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
     at java.lang.Thread.run(Thread.java:662)

Thanks!

On 12/22/2011 03:46 PM, Stefan Guggisberg wrote:
> On Thu, Dec 22, 2011 at 8:39 PM, Mat Lowery<mlowery@pentaho.com>  wrote:
>> 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.
> correct
>
>> 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.
> strange. i ran your test 20 times in a row on my macbook pro (os-x
> 10.7, java 6)
> against the current head (svn r1222443). none of the runs failed.
>
> cheers
> stefan
>
>> 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