jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefan Guggisberg <stefan.guggisb...@gmail.com>
Subject Re: concurrency problem
Date Mon, 08 Aug 2005 17:08:28 GMT
On 8/8/05, Nicolas Belisle <Nicolas.Belisle@bibl.ulaval.ca> 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/jackrabbit-dev@incubator.apache.org/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.");
> >         }
> >}
> >
> >
> 
>

Mime
View raw message