I've managed to make some basic case that throws the error every time.
import org.apache.jackrabbit.core.TransientRepository;
import javax.jcr.*;
public class JCRConcurrency
{
public static void main(String[] args) throws RepositoryException
{
Repository repo;
if (args.length >= 2)
repo = new TransientRepository(args[0], args[1]);
else
repo = new TransientRepository();
SimpleCredentials simpleCredentials = new SimpleCredentials("username",
"password".toCharArray());
Session sessionInit = repo.login(simpleCredentials);
// initialization
Node root = sessionInit.getRootNode();
Node test;
if (root.hasNode("test"))
test = root.getNode("test");
else
test = root.addNode("test");
if (!test.hasProperty("property"))
test.setProperty("property", 0);
sessionInit.save();
String testIdentifier = test.getIdentifier();
// session 1
Session session1 = repo.login(simpleCredentials);
Node test1 = session1.getNodeByIdentifier(testIdentifier);
System.out.println(test1.getProperty("property").getLong());
test1.setProperty("property", 1);
// session 2 is doing some other things at the same time
Session session2 = repo.login(simpleCredentials);
Node test2 = session2.getNodeByIdentifier(testIdentifier);
test2.setProperty("property", 2);
// session 2 saves first
session2.save();
session2.logout();
// session 1 saves
session1.save();
session1.logout();
sessionInit.logout();
System.exit(0);
}
}
Le 2010-12-10 à 6:12 PM, François Cassistat a écrit :
> Hi list !
>
> I've got some concurrency problem while saving. My application use distinct
> Sessions object and when two processes are trying to modify the same property
> of the same node at the same time. I've get the exception below :
> javax.jcr.InvalidItemStateException: Item cannot be saved because it has been
> modified externally: node /
> at
> org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:249)
> at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:981)
> at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:920)
> at com.myproject.MyProject.save(MyProject.java:1525)
> ...
>
>
> I have tried saving this way :
> synchronized (this)
> {
> session.refresh(true);
> session.save();
> }
>
>
> Is there any way around or only locks and transactions can prevent that ?
>
>
> Thanks !
>
>
> François
>