Hi Walter,

The problem is that the root Node is concurrently read & modified.

Case :
s0 : Read the rootNode
s1 : Read the rootNode
s0 : Modify rootNode : remove testnode-s0 & save()
s1 : Modify rootNode : remove testnode-s1 & save() -->ERROR the rootNode contains a reference to an removed node : "testnode-s0"

Note: session.save() justs saves the root Node under the covers. If you put your nodes in a structure like /s0/testnode-s0 your test will succeed.

Am I making sense ? or I also get damaged by to much sun in my vacation :-) ?

I also detailed some problems I had with concurrent sessions in the following thread : http://www.mail-archive.com/[email protected]/msg01677.html

I do agree that this behavior is a bit strange (why addNode() does not produce the same exceptions?)...


Regards,

Nicolas


Le 12:02 2005-08-06, vous avez écrit:
Hi all,

I wrote a simple test to simulate some concurrent sessions. But the test fails with exceptions. Is this a bug or do I get damaged by to much sun in my short vacation?

It happens with CQFileSystem and LocalFileSystem with all persistence managers.

cheers,
Walter

--
run 1 (empty repository):
=========================
s0: started.
s1: started.
s2: started.
s3: started.
s4: started.
.................................................s0: ended.
.s1: ended.
s2: ended.
s3: ended.
s4: ended.


run 2 (data from run 1):
========================
s0: started.
s1: started.
s2: started.
s3: started.
s4: started.
s2: Exception: removing testnode
javax.jcr.nodetype.ConstraintViolationException: 3b2fe68b-7747-459d-92b2-216b0af472e2 needs to be saved as well.
        at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1289)
        at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
        at TestSession.run(TestSession.java:61)
        at java.lang.Thread.run(Unknown Source)
s3: Exception: removing testnode
javax.jcr.nodetype.ConstraintViolationException: 3b2fe68b-7747-459d-92b2-216b0af472e2 needs to be saved as well.
        at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1289)
        at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
        at TestSession.run(TestSession.java:61)
        at java.lang.Thread.run(Unknown Source)
s3: ended.
s2: ended.
s4: Exception: removing testnode
javax.jcr.nodetype.ConstraintViolationException: 1dca23f9-e6d5-47b3-830c-a272b9387925 needs to be saved as well.
        at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1289)
        at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
        at TestSession.run(TestSession.java:61)
        at java.lang.Thread.run(Unknown Source)
s4: ended.
s0: Exception: adding testnode
javax.jcr.ItemNotFoundException: 3b2fe68b-7747-459d-92b2-216b0af472e2
at org.apache.jackrabbit.core.ItemManager.createItemInstance(ItemManager.java:498) at org.apache.jackrabbit.core.ItemManager.getItem(ItemManager.java:349) at org.apache.jackrabbit.core.NodeImpl.internalAddChildNode(NodeImpl.java:781) at org.apache.jackrabbit.core.NodeImpl.internalAddNode(NodeImpl.java:725) at org.apache.jackrabbit.core.NodeImpl.internalAddNode(NodeImpl.java:672)
        at org.apache.jackrabbit.core.NodeImpl.addNode(NodeImpl.java:1721)
        at TestSession.run(TestSession.java:69)
        at java.lang.Thread.run(Unknown Source)
s0: ended.
..........s1: ended.


Source:
=======

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Value;

import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.config.RepositoryConfig;

public class JackRabbitTest {

        public static void performanceTest(Repository r) {
                try {
                        for( int i=0; i<5; i++ ) {
Session session = r.login(new SimpleCredentials("admin", "".toCharArray()), null); TestSession ts = new TestSession("s" + i, session);
                                Thread th = new Thread(ts);
                                th.start();
                                Thread.sleep(100);
                        }
                } catch (Exception e){
                        System.err.println(e);
                    e.printStackTrace();
                }
        }

        public static void main(String[] args) {
                try {
                      String configFile = "repository.xml";
                      String repHomeDir = "repository.home";

RepositoryConfig c = RepositoryConfig.create(configFile, repHomeDir);
                      Repository r = RepositoryImpl.create(c);

                      performanceTest(r);
                    } catch (Exception e){
                      System.err.println(e);
                      e.printStackTrace();
                    }
        }
}
------------
import java.util.Random;

import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.Session;
import javax.jcr.lock.Lock;

import org.apache.jackrabbit.value.StringValue;

public class TestSession implements Runnable {

        Session session;
        String identity;
        Random r;

        TestSession( String identity, Session s ) {
                this.session = s;
                this.identity = identity;
                r = new Random();
        }

        private void debug(String msg) {
                System.out.println( identity + ": " + msg);
        }

        private void sleep() {
                long l = r.nextInt(900)+200;
                try {
                        Thread.sleep( l );
                } catch(InterruptedException ie) {
                }
        }

        public void run() {

                debug("started.");
                String state = "";
                try {
                        Node rn = session.getRootNode();

                        state = "searching testnode";
                        if (rn.hasNode("testnode-" + identity)) {
                        try {
                                state = "removing testnode";
                                rn.getNode("testnode-" + identity).remove();
                                session.save();
                                sleep();
                        } catch(ItemNotFoundException infe) {
debug("error while removing testnode " + identity);
                                infe.printStackTrace();
                        }
                    }
                state = "adding testnode";
Node n = rn.addNode("testnode-" + identity , "nt:unstructured");

                    session.save();
                    state = "setting property";
n.setProperty("testprop", new StringValue("Hello World!"));
                    session.save();
                    sleep();

                    for(int i=0; i<100; i++) {
                        state = "adding subnode " + i;
                        n.addNode("x" + i, "nt:unstructured");
                        state = "adding property to subnode " + i;
                        n.setProperty("testprop","xxx");
                        if(i%10==0)     {
                                state = "saving pending subnodes";
                                session.save();
                                System.out.print(".");
                        }
                        sleep();
                    }
                    session.save();

                } catch( Exception e) {
                        debug("Exception: " + state);
                        e.printStackTrace();
                } finally {
                        session.logout();
                }

                debug("ended.");
        }
}



Reply via email to