jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From François Cassistat...@maya-systems.com>
Subject Re: Item cannot be saved because it has been modified externally: node /
Date Tue, 14 Dec 2010 16:05:08 GMT
At least, in your text editor example, the user have the choice to override. But I understand
it is a JCR limitation, not Jackrabbit.

I'll try finding a solution using locks and maybe a complementary secondary database system
for properties that need to be changed frequently to prevent locking to much nodes.

Thank you Stefan for your assistance,


François



Le 2010-12-13 à 4:04 PM, Stefan Guggisberg a écrit :

> 2010/12/13 François Cassistat <f@maya-systems.com>:
>> Re-hi,
>> 
>> Thanks for your answers. I have tested with 2.3-SNAPSHOT and it still doesn't work...
Although, the exception message is better "property /test/property: the property cannot be
saved because it has been modified externally."
>> 
>> I do not understand why it should be an wanted behavior.
> 
> because it prevents you from accidentally overwriting changes made by
> other sessions.
> 
> just like a text editor application will warn you, that the document
> you're about to
> persist had been modified by somebody else after you've opened it for editing.
> 
> there are different ways to handle such situations, and i guess none
> is the ultimate
> 'correct way'. it depends on the use case.
> 
> if your application must concurrently modify a specific property then you should
> use locking. that's what locks are intended for.
> 
> cheers
> stefan
> 
>> Does Jackrabbit is designed to work with Node locks and Transaction only? There is
no way to take the changes I've made in one Session and retry them? Based on my analysis :
>> - Transaction would slow down the repository...
>> - Locked nodes looks complicated and deadlock friendly since I need to modify properties
at many place in the repository at once.
>> - Retrying to get a new session and remake the changes when there was an error at
session.save() looks like a dirty solution to me.
>> 
>> Maybe there is something I did not understand with jackrabbit concurrency model.
Any pointers?
>> 
>> 
>> François
>> 
>> 
>> 
>> Le 2010-12-13 à 4:33 AM, Stefan Guggisberg a écrit :
>> 
>>> On Sat, Dec 11, 2010 at 11:52 AM, Norman Maurer <norman@apache.org> wrote:
>>>> Hi there,
>>>> 
>>>> this is fixed in the upcomming jackrabbit 2.2.0 (which should be
>>>> released within the next days). In the meantime you can grab a
>>>> snapshot here:
>>>> 
>>>> https://repository.apache.org/content/groups/snapshots/org/apache/jackrabbit/
>>>> 
>>>> Version name is 2.2-SNAPSHOT.
>>> 
>>> sorry, but i have to contradict norman.
>>> 
>>> the following behavior is as per design:
>>> 
>>> 1. sessionA modifies a property
>>> 2. sessionB modifies the same property and saves its changes
>>> 3. sessionA tries to save its changes but fails with a
>>> InvalidItemStateException because its changes have become stale
>>> 
>>> this is the behavior as implemented in trunk.
>>> 
>>> cheers
>>> stefan
>>> 
>>>> 
>>>> Bye,
>>>> Norman
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 2010/12/11 François Cassistat <f@maya-systems.com>:
>>>>> 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
>>>>>> 
>>>>> 
>>>>> 
>>>> 
>> 
>> 


Mime
View raw message