On 20 Mar 2009, at 08:41, Stefan Guggisberg wrote:

On Fri, Mar 20, 2009 at 9:05 AM, Marc Speck <[email protected]> wrote:
It looks like you always load the same item "randomFile1". Let's say that threadA and threadB fetch randomFile1, then threadA saves the change with session.save(). When threadB wants to save, it notices that randomFile1 has
been changed by an other thread since it loaded it and throws an
InvalidItemStateException. This is an expected behaviour of Jackrabbit.

absolutely correct. non-conflicting concurrent node modifications are merged
silently, the aforementioned test case however includes non-mergable
conflicting
changes (the same property is written/removed by multiple threads). for more
information please see [1].

Yes I read [1] on my search and a similar thread from Jullian in April 2008 on the dev list (Concurrent Modifications).

Unfortunately building a hashed tree of folders results in non- mergable changes.
before
/store/ab

thread1
/store/ab/ed/8c/data.json

thread2
/store/ab/ed/8c/otherdata.json

the creation of ed is a non mergable change, and I don't fancy creating the 255^3 nodes to avoid the problem.

besides, with a multiuser system, randomness will ensure that at some point *every* change is potentially non-mergable. Propagating the exception to users will in most cases not be acceptable. (eg sorry your PhD was not granted because of a non-mergable change :)... this is for Higher Ed)

What's the best approach for handling this ?
Locking (JCR or external) ?
    slows everything down
Exception Recovery strategy inside the request (ie resubmit) ?
   complex

Ian



cheers
stefan

[1] https://issues.apache.org/jira/browse/JCR-584




On Fri, Mar 20, 2009 at 12:07 AM, Ian Boston <[email protected] >wrote:



If I run the test below I reliably get the following exception, any
ideas, what should I be doing that I am not.

This is jackrabbit core 1.4.8

(btw jcrService performs logins into the repository, that has a
BundlePersistanceManager and a ClusterNode configuration, running on
Derby. There is no TransactionManager in this test)



javax.jcr.InvalidItemStateException: e13c3bca-2d00-4717-
af77-02c385b10351/{http://www.sakaiproject.org/CHS/jcr/jackrabbit/
1.0}test has been modified externally
at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java: 1251) at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:897) at org.sakaiproject.kernel.util.JcrUtilsT $1.run(JcrUtilsT.java:137)
       at java.lang.Thread.run(Thread.java:613)

 @Test
 public void multiThreadTest() throws Exception {
   Thread[] t = new Thread[20];
   running = 0;
   for (int i = 0; i < t.length; i++) {
     t[i] = new Thread(new Runnable() {

       public void run() {
         running++;
         Random random = new Random();
         try {
           for (int i = 0; i < 20; i++) {
             try {
               Session session = jcrService.loginSystem();
               Node node = (Node) session.getItem(randomFile1);
               try {
                 node.getProperty("sakaijcr:test").remove();
               } catch (Exception e) {

               }
               session.save();
               Thread.yield();
               node.setProperty("sakaijcr:test", "new
value"+random.nextLong());
               session.save();
             } catch (Exception e) {
               e.printStackTrace();
             } finally {
               try {
                 jcrService.logout();
               } catch (Exception e) {
                 e.printStackTrace();
               }
             }
           }
         } finally {
           running--;
         }
       }

     });
   }
   for (int i = 0; i < t.length; i++) {
     t[i].start();
     Thread.yield();
   }

   while (running > 0) {
     Thread.yield();
   }

 }



Reply via email to