You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by Walter Raboch <wr...@ingen.at> on 2005/08/06 18:02:03 UTC
concurrency problem
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.");
}
}
Re: concurrency problem
Posted by Stefan Guggisberg <st...@gmail.com>.
hi walter,
On 8/22/05, Walter Raboch <wr...@ingen.at> wrote:
> Hi Stefan,
>
> >>the first InvalidItemStateException is correct.
> >>i'll investigate the ItemNotFoundException. i guess there's
> >>a 'synchronized' missing somewhere...
> >
> > this issue should be fixed now (r233511).
>
> JackRabbit is still hanging on the Node.unlock() function.
that's a new issue. please post a jira bug with detailed instructions
how to reporduce the problem.
thanks
stefan
>
> ... everything fine until here...
> s13: 4
> s13: 5
> s13: 6
> s13: 7 -> unlock()
> s14: started.
> s14: 1 -> session.getRootNode()
> s15: started.
> s15: 1
> s16: started.
>
> I just find this failure during the first run (emtpy repository home
> directory). 2nd and 3th run are fine after killing the vm from first
> run, but with already initialized repository directory these time.
>
> 1. rm -rf repository.home
> 2. run -> hang
> 3. kill
> 4. run -> ok
> 5. run -> ok
>
> cheers,
> Walter
>
>
Re: concurrency problem
Posted by Walter Raboch <wr...@ingen.at>.
Hi Stefan,
>>the first InvalidItemStateException is correct.
>>i'll investigate the ItemNotFoundException. i guess there's
>>a 'synchronized' missing somewhere...
>
> this issue should be fixed now (r233511).
JackRabbit is still hanging on the Node.unlock() function.
... everything fine until here...
s13: 4
s13: 5
s13: 6
s13: 7 -> unlock()
s14: started.
s14: 1 -> session.getRootNode()
s15: started.
s15: 1
s16: started.
I just find this failure during the first run (emtpy repository home
directory). 2nd and 3th run are fine after killing the vm from first
run, but with already initialized repository directory these time.
1. rm -rf repository.home
2. run -> hang
3. kill
4. run -> ok
5. run -> ok
cheers,
Walter
Re: concurrency problem
Posted by Stefan Guggisberg <st...@gmail.com>.
On 8/11/05, Stefan Guggisberg <st...@gmail.com> wrote:
> On 8/11/05, Walter Raboch <wr...@ingen.at> wrote:
> > Hi Stefan,
> >
> > >>Thanks for the discussion. Now I unterstand jackrabbits way of doing.
> > >>But in my opinion adding child nodes should not alter the parent node
> > >>itself. Just changing some properties is a state change.
> > >
> > > i don't agree. see 7.1.4 Adding Nodes in the jsr 170 spec:
> > > <quote>
> > > In order to save a newly added node, save must be called either on the
> > > Session, or on the new node's parent or higher-order ancestor
> > > (grandparent, etc.).
> > > </quote>
> > >>Furthermore there should be an error just in the case, that both updates
> > >>overwrite the changes of the other -> to prevent lost update problems.
> > >>In my example code it´s not the case, so I would prefer no error at all.
> > >>What do you think?
> > >
> > > AFAIK lost updates did never happen. your testcase failed in the right
> > > situations
> > > but threw the wrong exceptions. i committed a fix for that problem yesterday.
> > > IMO it now works as it should according to the jsr 170 spec.
> >
> > You are right according to the spec. Let me try to explain my thoughts:
> >
> > s0: read root node
> > s1: read root node
> > s0: add or remove child "c1"
> > s1: add or remove child "c2"
> > s0: rn.save()
> > s1: rn.save()
> >
> > All this without error. Because the changes of both sessions dont
> > interfere.
>
> i can see what you mean. unfortunately there's no trivial solution.
> child node additions & removals per se are not guaranteed to
> be non-interfering. there's even a great chance that they actually
> *are* interfering. just think of same-name siblings. the same applies
> for child re-ordering.
>
> an application should lock the parent node to stay clear of such
> concurrency issues (pessimistic locking approach).
>
> > If both sessions change the same child or attribute, there should be
> > thrown an InvalidItemStateException.
> >
> > s0: read root node
> > s1: read root node
> > s0: set property p="hello"
> > s1: set property p="world"
> > s0: save
> > s1: save -> InvalidItemStateException
> >
> > What do you think?
> >
> > To our first problem with my testcase. I rerun the code but it still
> > fails with ItemNotFoundExceptions. But I dont know why.
>
> the first InvalidItemStateException is correct.
> i'll investigate the ItemNotFoundException. i guess there's
> a 'synchronized' missing somewhere...
this issue should be fixed now (r233511).
cheers
stefan
>
> cheers
> stefan
>
> >
> > cheers, Walter
> > --
> > Output of rerun (revision 231423):
> > ==================================
> > s0: started.
> > s1: started.
> > s2: started.
> > s3: started.
> > s4: started.
> > s3: Exception: removing testnode
> > javax.jcr.InvalidItemStateException: /: the item cannot be saved because
> > it has been modified externally.
> > at
> > org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:347)
> > at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1205)
> > at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
> > at TestSession.run(TestSession.java:62)
> > at java.lang.Thread.run(Unknown Source)
> > s3: ended.
> > javax.jcr.ItemNotFoundException: 545ab69b-0297-427c-a05a-217e3c8f7d88
> > 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:70)
> > at java.lang.Thread.run(Unknown Source)
> > s0: Exception: adding testnode
> > s0: ended.
> > s4: Exception: removing testnode
> > javax.jcr.InvalidItemStateException: /: the item cannot be saved because
> > it has been modified externally.
> > at
> > org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:347)
> > at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1205)
> > at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
> > at TestSession.run(TestSession.java:62)
> > at java.lang.Thread.run(Unknown Source)
> > s4: ended.
> > s1: Exception: adding testnode
> > javax.jcr.ItemNotFoundException: e170d490-b7c1-4dfa-be14-f8932162b9f7
> > 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:70)
> > at java.lang.Thread.run(Unknown Source)
> > s1: ended.
> > ..........s2: ended.
> >
> >
> >
>
Re: concurrency problem
Posted by Nicolas Belisle <Ni...@bibl.ulaval.ca>.
Hi Waler,
I invested some efforts to create a template class implementing
waitForLock() functionality. It respects the JSR, so it can be used with
any implementation that supports locking.
You can read about it here :
http://www.mail-archive.com/jackrabbit-dev%40incubator.apache.org/msg01870.html
Note: I haven't used it in production. I also welcome any comments...
Regards,
Nicolas
Le 10:29 2005-08-11, vous avez écrit:
>Hi Stefan,
>
>>the first InvalidItemStateException is correct. i'll investigate the
>>ItemNotFoundException. i guess there's a 'synchronized' missing somewhere...
>
>I extended my testcase a little bit. Now I lock the rootnode for
>adding/deleting subnodes. But the program hangs sometimes while
>locking or releasing the lock again.
>
>Some waitForLock() method would be cool too ;) Perhaps with
>some sort of waitQueue. But I know - its not in the spec.
>
>cheers,
>Walter
>--
>
>public void run() {
> // simulate a user...
> debug("started.");
> String state = "";
> Lock l = null;
> Node rn = null;
> try {
> debug("1");
> rn = session.getRootNode();
> debug("2");
> int count = 0;
> while(rn.isLocked() && count < 30) {
> sleep();
> count++;
> }
> debug("3");
> l = rn.lock(false, true);
> debug("4");
> state = "searching testnode";
> if (rn.hasNode("testnode-" + identity)) {
> debug("4.1");
> try {
> state = "removing testnode";
> rn.getNode("testnode-" + identity).remove();
> debug("4.2");
> session.save();
> sleep();
> } catch(ItemNotFoundException infe) {
> debug("error while removing testnode " +
> identity);
> infe.printStackTrace();
> }
> }
> debug("5");
> state = "adding testnode";
> Node n = rn.addNode("testnode-" + identity ,
> "nt:unstructured");
> debug("6");
> session.save();
> debug("7");
> rn.unlock();
> debug("8");
> 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 {
> if(l != null && rn != null) {
> try {
> rn.unlock();
> } catch( RepositoryException e )
> {
> }
> }
> session.logout();
> }
>
> debug("ended.");
> }
Re: concurrency problem
Posted by Walter Raboch <wr...@ingen.at>.
Hi Stefan,
> the first InvalidItemStateException is correct.
> i'll investigate the ItemNotFoundException. i guess there's
> a 'synchronized' missing somewhere...
I extended my testcase a little bit. Now I lock the rootnode for
adding/deleting subnodes. But the program hangs sometimes while
locking or releasing the lock again.
Some waitForLock() method would be cool too ;) Perhaps with
some sort of waitQueue. But I know - its not in the spec.
cheers,
Walter
--
public void run() {
// simulate a user...
debug("started.");
String state = "";
Lock l = null;
Node rn = null;
try {
debug("1");
rn = session.getRootNode();
debug("2");
int count = 0;
while(rn.isLocked() && count < 30) {
sleep();
count++;
}
debug("3");
l = rn.lock(false, true);
debug("4");
state = "searching testnode";
if (rn.hasNode("testnode-" + identity)) {
debug("4.1");
try {
state = "removing testnode";
rn.getNode("testnode-" + identity).remove();
debug("4.2");
session.save();
sleep();
} catch(ItemNotFoundException infe) {
debug("error while removing testnode " + identity);
infe.printStackTrace();
}
}
debug("5");
state = "adding testnode";
Node n = rn.addNode("testnode-" + identity , "nt:unstructured");
debug("6");
session.save();
debug("7");
rn.unlock();
debug("8");
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 {
if(l != null && rn != null) {
try {
rn.unlock();
} catch( RepositoryException e ) {
}
}
session.logout();
}
debug("ended.");
}
Re: concurrency problem
Posted by Stefan Guggisberg <st...@gmail.com>.
On 8/11/05, Walter Raboch <wr...@ingen.at> wrote:
> Hi Stefan,
>
> >>Thanks for the discussion. Now I unterstand jackrabbits way of doing.
> >>But in my opinion adding child nodes should not alter the parent node
> >>itself. Just changing some properties is a state change.
> >
> > i don't agree. see 7.1.4 Adding Nodes in the jsr 170 spec:
> > <quote>
> > In order to save a newly added node, save must be called either on the
> > Session, or on the new node's parent or higher-order ancestor
> > (grandparent, etc.).
> > </quote>
> >>Furthermore there should be an error just in the case, that both updates
> >>overwrite the changes of the other -> to prevent lost update problems.
> >>In my example code it´s not the case, so I would prefer no error at all.
> >>What do you think?
> >
> > AFAIK lost updates did never happen. your testcase failed in the right
> > situations
> > but threw the wrong exceptions. i committed a fix for that problem yesterday.
> > IMO it now works as it should according to the jsr 170 spec.
>
> You are right according to the spec. Let me try to explain my thoughts:
>
> s0: read root node
> s1: read root node
> s0: add or remove child "c1"
> s1: add or remove child "c2"
> s0: rn.save()
> s1: rn.save()
>
> All this without error. Because the changes of both sessions dont
> interfere.
i can see what you mean. unfortunately there's no trivial solution.
child node additions & removals per se are not guaranteed to
be non-interfering. there's even a great chance that they actually
*are* interfering. just think of same-name siblings. the same applies
for child re-ordering.
an application should lock the parent node to stay clear of such
concurrency issues (pessimistic locking approach).
> If both sessions change the same child or attribute, there should be
> thrown an InvalidItemStateException.
>
> s0: read root node
> s1: read root node
> s0: set property p="hello"
> s1: set property p="world"
> s0: save
> s1: save -> InvalidItemStateException
>
> What do you think?
>
> To our first problem with my testcase. I rerun the code but it still
> fails with ItemNotFoundExceptions. But I dont know why.
the first InvalidItemStateException is correct.
i'll investigate the ItemNotFoundException. i guess there's
a 'synchronized' missing somewhere...
cheers
stefan
>
> cheers, Walter
> --
> Output of rerun (revision 231423):
> ==================================
> s0: started.
> s1: started.
> s2: started.
> s3: started.
> s4: started.
> s3: Exception: removing testnode
> javax.jcr.InvalidItemStateException: /: the item cannot be saved because
> it has been modified externally.
> at
> org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:347)
> at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1205)
> at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
> at TestSession.run(TestSession.java:62)
> at java.lang.Thread.run(Unknown Source)
> s3: ended.
> javax.jcr.ItemNotFoundException: 545ab69b-0297-427c-a05a-217e3c8f7d88
> 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:70)
> at java.lang.Thread.run(Unknown Source)
> s0: Exception: adding testnode
> s0: ended.
> s4: Exception: removing testnode
> javax.jcr.InvalidItemStateException: /: the item cannot be saved because
> it has been modified externally.
> at
> org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:347)
> at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1205)
> at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
> at TestSession.run(TestSession.java:62)
> at java.lang.Thread.run(Unknown Source)
> s4: ended.
> s1: Exception: adding testnode
> javax.jcr.ItemNotFoundException: e170d490-b7c1-4dfa-be14-f8932162b9f7
> 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:70)
> at java.lang.Thread.run(Unknown Source)
> s1: ended.
> ..........s2: ended.
>
>
>
Re: concurrency problem
Posted by Walter Raboch <wr...@ingen.at>.
Hi Stefan,
>>Thanks for the discussion. Now I unterstand jackrabbits way of doing.
>>But in my opinion adding child nodes should not alter the parent node
>>itself. Just changing some properties is a state change.
>
> i don't agree. see 7.1.4 Adding Nodes in the jsr 170 spec:
> <quote>
> In order to save a newly added node, save must be called either on the
> Session, or on the new node's parent or higher-order ancestor
> (grandparent, etc.).
> </quote>
>>Furthermore there should be an error just in the case, that both updates
>>overwrite the changes of the other -> to prevent lost update problems.
>>In my example code it´s not the case, so I would prefer no error at all.
>>What do you think?
>
> AFAIK lost updates did never happen. your testcase failed in the right
> situations
> but threw the wrong exceptions. i committed a fix for that problem yesterday.
> IMO it now works as it should according to the jsr 170 spec.
You are right according to the spec. Let me try to explain my thoughts:
s0: read root node
s1: read root node
s0: add or remove child "c1"
s1: add or remove child "c2"
s0: rn.save()
s1: rn.save()
All this without error. Because the changes of both sessions dont
interfere.
If both sessions change the same child or attribute, there should be
thrown an InvalidItemStateException.
s0: read root node
s1: read root node
s0: set property p="hello"
s1: set property p="world"
s0: save
s1: save -> InvalidItemStateException
What do you think?
To our first problem with my testcase. I rerun the code but it still
fails with ItemNotFoundExceptions. But I dont know why.
cheers, Walter
--
Output of rerun (revision 231423):
==================================
s0: started.
s1: started.
s2: started.
s3: started.
s4: started.
s3: Exception: removing testnode
javax.jcr.InvalidItemStateException: /: the item cannot be saved because
it has been modified externally.
at
org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:347)
at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1205)
at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
at TestSession.run(TestSession.java:62)
at java.lang.Thread.run(Unknown Source)
s3: ended.
javax.jcr.ItemNotFoundException: 545ab69b-0297-427c-a05a-217e3c8f7d88
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:70)
at java.lang.Thread.run(Unknown Source)
s0: Exception: adding testnode
s0: ended.
s4: Exception: removing testnode
javax.jcr.InvalidItemStateException: /: the item cannot be saved because
it has been modified externally.
at
org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:347)
at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1205)
at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:747)
at TestSession.run(TestSession.java:62)
at java.lang.Thread.run(Unknown Source)
s4: ended.
s1: Exception: adding testnode
javax.jcr.ItemNotFoundException: e170d490-b7c1-4dfa-be14-f8932162b9f7
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:70)
at java.lang.Thread.run(Unknown Source)
s1: ended.
..........s2: ended.
Re: concurrency problem
Posted by Stefan Guggisberg <st...@gmail.com>.
hi walter,
On 8/10/05, Walter Raboch <wr...@ingen.at> wrote:
> Hi Stefan,
>
> > 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
>
> there should be no error at this point, s0 has not been saved yet.
absolutely correct, i haven't been careful enough when i copy/pasted it,
sorry for that. let me try again;)
s0 : Read the rootNode
s1 : Read the rootNode
s0 : Modify rootNode : remove testnode-s0
s1 : Modify rootNode : remove testnode-s1
s0 : save()
s1 : save() -->InvalidItemStateException since the root node has been externally
modifiied (by s0); s1's 'copy' has become stale as a result
>
> > s0 : save()
>
> now there should be an error since s1 saved its state before
>
> > s1 : save() -->InvalidItemStateException since the root node has been externally
> > modifiied (by s0) is has s1's 'copy' has become stale as a result
>
> I dont think that here should be an error, since the last saved
> (commited) version of the rootNode is from s1 and the changes from s0
> has not been valid and not commited. so the nodes state has not changed.
>
> > we'll fix that asap.
>
> Thanks for the discussion. Now I unterstand jackrabbits way of doing.
> But in my opinion adding child nodes should not alter the parent node
> itself. Just changing some properties is a state change.
i don't agree. see 7.1.4 Adding Nodes in the jsr 170 spec:
<quote>
In order to save a newly added node, save must be called either on the
Session, or on the new node's parent or higher-order ancestor
(grandparent, etc.).
</quote>
>
> Furthermore there should be an error just in the case, that both updates
> overwrite the changes of the other -> to prevent lost update problems.
> In my example code it´s not the case, so I would prefer no error at all.
> What do you think?
AFAIK lost updates did never happen. your testcase failed in the right
situations
but threw the wrong exceptions. i committed a fix for that problem yesterday.
IMO it now works as it should according to the jsr 170 spec.
cheers
stefan
>
> cheers,
> Walter
>
>
Re: concurrency problem
Posted by Walter Raboch <wr...@ingen.at>.
Hi Stefan,
> 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
there should be no error at this point, s0 has not been saved yet.
> s0 : save()
now there should be an error since s1 saved its state before
> s1 : save() -->InvalidItemStateException since the root node has been externally
> modifiied (by s0) is has s1's 'copy' has become stale as a result
I dont think that here should be an error, since the last saved
(commited) version of the rootNode is from s1 and the changes from s0
has not been valid and not commited. so the nodes state has not changed.
> we'll fix that asap.
Thanks for the discussion. Now I unterstand jackrabbits way of doing.
But in my opinion adding child nodes should not alter the parent node
itself. Just changing some properties is a state change.
Furthermore there should be an error just in the case, that both updates
overwrite the changes of the other -> to prevent lost update problems.
In my example code it´s not the case, so I would prefer no error at all.
What do you think?
cheers,
Walter
Re: concurrency problem
Posted by Stefan Guggisberg <st...@gmail.com>.
On 8/8/05, Nicolas Belisle <Ni...@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.");
> > }
> >}
> >
> >
>
>
Re: concurrency problem
Posted by Nicolas Belisle <Ni...@bibl.ulaval.ca>.
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/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?)...
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.");
> }
>}
>
>
Re: concurrency problem
Posted by Stefan Guggisberg <st...@gmail.com>.
hi walter,
thanks, i'll have a look at it asap.
cheers
stefan
On 8/6/05, Walter Raboch <wr...@ingen.at> wrote:
> 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.");
> }
> }
>
>
>
>