jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Boston <...@tfd.co.uk>
Subject Re: InvalidItemStateException with concurrent threads
Date Fri, 20 Mar 2009 09:36:39 GMT

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

> On Fri, Mar 20, 2009 at 9:05 AM, Marc Speck <marcspeck@gmail.com>  
> 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 <ianboston@googlemail.com 
>> >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();
>>>    }
>>>
>>>  }
>>>
>>


Mime
View raw message