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.");
}
}