Return-Path: Delivered-To: apmail-jackrabbit-users-archive@minotaur.apache.org Received: (qmail 58356 invoked from network); 20 Mar 2009 09:37:14 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 20 Mar 2009 09:37:14 -0000 Received: (qmail 99856 invoked by uid 500); 20 Mar 2009 09:37:12 -0000 Delivered-To: apmail-jackrabbit-users-archive@jackrabbit.apache.org Received: (qmail 99839 invoked by uid 500); 20 Mar 2009 09:37:12 -0000 Mailing-List: contact users-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@jackrabbit.apache.org Delivered-To: mailing list users@jackrabbit.apache.org Received: (qmail 99828 invoked by uid 99); 20 Mar 2009 09:37:12 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Mar 2009 02:37:12 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of ianboston@googlemail.com designates 209.85.219.171 as permitted sender) Received: from [209.85.219.171] (HELO mail-ew0-f171.google.com) (209.85.219.171) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Mar 2009 09:37:03 +0000 Received: by ewy19 with SMTP id 19so609762ewy.43 for ; Fri, 20 Mar 2009 02:36:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:received:received:sender:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:mime-version :subject:date:references:x-mailer; bh=2iCSacJugnhK6ylYvugWtOfeXGN34+E1e8haOnaw+ns=; b=vdSnJHw8KUmxQPaPgSk1m6OK2vqACOIETBbQw/u9Qi+oCeThsAYcBMCCLbxGriihBi ycq3ZyYPMrXKRgjCTwAWLJ6kzS6sA7d/DMWlY0sWp7g5f0R8efczp/Hj63y6kv1m66Mu whGCBrz1vXQy38POHpKNCghZg2Ghi9Lqzyn5k= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=sender:message-id:from:to:in-reply-to:content-type :content-transfer-encoding:mime-version:subject:date:references :x-mailer; b=BcDGvpmSkSVphAwIs9Ce82/Ww1UGRX+QrVlbntSlgwHTUrxDgqCtsYpu8nKKAS7ZA4 NinDNRbFR9eBTst2x3m9oHgYNQn1TQ2/4GVcCgqB+dPTcfRMh9mHraZTpdc33zQxLsTs T4RLrQo9lVwxKQ1vNo12UZai2ep6gQzxRKotU= Received: by 10.216.7.209 with SMTP id 59mr1312778wep.213.1237541801691; Fri, 20 Mar 2009 02:36:41 -0700 (PDT) Received: from ?192.168.115.101? (cpc6-papw1-0-0-cust601.cmbg.cable.ntl.com [86.1.46.90]) by mx.google.com with ESMTPS id i8sm3694434nfh.29.2009.03.20.02.36.40 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 20 Mar 2009 02:36:40 -0700 (PDT) Sender: Ian Boston Message-Id: <0888EFA6-2F26-4CDF-AE45-F470708F4A4B@tfd.co.uk> From: Ian Boston To: users@jackrabbit.apache.org In-Reply-To: <90a8d1c00903200141q4e551c67q8b26cdcf4c7bc739@mail.gmail.com> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v930.3) Subject: Re: InvalidItemStateException with concurrent threads Date: Fri, 20 Mar 2009 09:36:39 +0000 References: <6aaad09c0903200105g8817fb4v111e8efad1fbcd6d@mail.gmail.com> <90a8d1c00903200141q4e551c67q8b26cdcf4c7bc739@mail.gmail.com> X-Mailer: Apple Mail (2.930.3) X-Virus-Checked: Checked by ClamAV on apache.org On 20 Mar 2009, at 08:41, Stefan Guggisberg wrote: > On Fri, Mar 20, 2009 at 9:05 AM, Marc Speck > 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 > >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(); >>> } >>> >>> } >>> >>