On 8/8/05, Nicolas Belisle <[EMAIL PROTECTED]> wrote:
> 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 :-) ?
hehe;)
you're absolutely making sense. the reason why the test fails is concurrent
modifications. currently the wrong exceptions are thrown.
the correct beahviour should be:
s0 : Read the rootNode
s1 : Read the rootNode
s0 : Modify rootNode : remove testnode-s0
s1 : Modify rootNode : remove testnode-s1 & save() -->ERROR the rootNode
s0 : save()
s1 : save() -->InvalidItemStateException since the root node has been externally
modifiied (by s0) is has s1's 'copy' has become stale as a result
we'll fix that asap.
btw: you can avoid this situation if you lock the node beforehand.
cheers
stefan
> contains a reference to an removed node : "testnode-s0"
>
> 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?)...
Node.addNode() is a transient modification without affecting shared state.
cheers
stefan
>
>
> 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.");
> > }
> >}
> >
> >
>
>