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 <[email protected]>: >> 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 <[email protected]> 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 <[email protected]>: >>>>> 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 >>>>>> >>>>> >>>>> >>>> >> >>
