You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jackrabbit.apache.org by Torsten Curdt <tc...@apache.org> on 2009/01/04 20:07:35 UTC

concurrent writes

I am wondering how "concurrent" writes are handled with
jcr/jackrabbit. While the spec (4.1.3.2 Transient Storage in the
Session) does answer some of the questions I was wondering about some
of the details.

Let's say I have two people A and B editing a node from a JCR
repository. Both hold a reference to the node concurrently in
different sessions. Both modify some properties. Now A saves his
session, then B saves his session. IIUC the repository would now show
the state of B's session as B was essentially last. Assuming the node
has mixin mix:versionable I would expect to revisions like

1 original
2 from A
3 from B

Are these assumptions correct?

Would there be any sign/notification (exception/return code) for B
that the node he wants to write to was changed by A?

cheers
--
Torsten

RE: concurrent writes

Posted by 류대원 <dw...@nhncorp.com>.
Hi, 
In that case, if you want to prevent B's writing, A has to lock the node before writing.
I don't think B could receive any notification of changes by A.

And without lock mechanism, your assumptions are correct.

won

-----Original Message-----
From: tcurdt@vafer.org [mailto:tcurdt@vafer.org] On Behalf Of Torsten Curdt
Sent: Monday, January 05, 2009 4:08 AM
To: users@jackrabbit.apache.org
Subject: concurrent writes

I am wondering how "concurrent" writes are handled with
jcr/jackrabbit. While the spec (4.1.3.2 Transient Storage in the
Session) does answer some of the questions I was wondering about some
of the details.

Let's say I have two people A and B editing a node from a JCR
repository. Both hold a reference to the node concurrently in
different sessions. Both modify some properties. Now A saves his
session, then B saves his session. IIUC the repository would now show
the state of B's session as B was essentially last. Assuming the node
has mixin mix:versionable I would expect to revisions like

1 original
2 from A
3 from B

Are these assumptions correct?

Would there be any sign/notification (exception/return code) for B
that the node he wants to write to was changed by A?

cheers
--
Torsten



Re: concurrent writes

Posted by Marcel Reutegger <ma...@gmx.net>.
Torsten Curdt wrote:
>> See:
>> http://www.day.com/specs/jcr/1.0/7.1.1.4_Invalid_States.html
> 
> Maybe I am just reading it wrong but I still don't think this is
> precisely answering the question. For one it says "The altered item in
> the Session remains and may be saved later" and then "Note that this
> is precisely the same situation as would arise if a change were made
> to a workspace through another Session. In both cases the save on this
> Session may throw an InvalidItemStateException."

ah, right. that section only covers conflicts with direct-to-workspace
operations. I think this one describes it in a more generic way:

http://www.day.com/specs/jcr/1.0/7.1.3.3_Invalid_Items.html


regards
 marcel

Re: concurrent writes

Posted by Alexander Klimetschek <ak...@day.com>.
I think the SQL comparison was a rough one, not one to take as 100% the same.

In the JCR API, a transaction can contain anything, it will happen
once you save. So you can add a node and save it, but you can also add
a node, add properties to it and save. Same for modifiying data by
getting a node and changing or adding properties on it.

If you don't use locking, Jackrabbit employs an optimistic strategy
(it's not mandated by the standard, see also copy-on-write vs.
copy-on-read [1] [2]). This means you will get an exception on save if
there is a conflict from another session. This allows you to handle
that issue in the application.

[1] http://wiki.apache.org/jackrabbit/JcrSpecImplementation
[2] http://www.day.com/specs/jcr/1.0/7.1.3.4_Seeing_Changes_Made_by_Other_Sessions.html

Regards,
Alex

On Mon, Jan 12, 2009 at 10:39 AM, Phil Weighill-Smith
<ph...@volantis.com> wrote:
> I have a (perhaps dumb) question about one of the points raised in the
> linked issue (JCR-1552):
>
> https://issues.apache.org/jira/browse/JCR-1552?focusedCommentId=12592051#action_12592051
>
> Here you state that creating a child node is like a SQL INSERT, whilst
> setting a property is like a SQL UPDATE; the implication is that a node
> is like a row and a property is like a column.
>
> In that case, is it possible to set a property during the creation of a
> node? If not, then surely setting a property the very first time should
> be equivalent to a SQL INSERT - after all an INSERT allows all columns
> to be assigned values during initial creation of the row; you are not
> required to do both an INSERT and an UPDATE.
>
> Or is it that the JCR API structure simply prevents an implementation
> from handling this case (seems unlikely)? (Yes, I can see that it may
> require the implementation to maintain additional internal state to
> handle the case, but it seems doable.)
>
> My concern is that whilst at the JCR level locking may be a nice and
> easy solution this doesn't always fit well with clients; we have an
> application using a non-JCR content repository that essentially does
> optimistic locking; we allow any number of users to perform concurrent
> viewing and/or editing of nodes and on save handle conflicts by allowing
> automatic and (when needed) manual merges.
>
> We are looking to leverage JCR and Jackrabbit in an updated version of
> the application, so this behaviour is relatively important to us - it
> needs to be clearly documented and consistent (plus, obviously,
> conformant with the specification). I would think that we can work
> around it either way with a combination of version detection and
> short-term node locking during write.
>
> Phil :n.
>
> On Tue, 2009-01-06 at 10:17 +0100, Jukka Zitting wrote:
>
>> Hi,
>>
>> On Mon, Jan 5, 2009 at 2:16 PM, Torsten Curdt <tc...@apache.org> wrote:
>> > Thanks! That links was very interesting ...not sure it gives a final
>> > answer though.
>>
>> Yeah, we never got around to going through the code based on the
>> results of that discussion.
>>
>> You may want to file a bug report about the setProperty behaviour. A
>> set of concurrent setProperty calls (with no Node.addNode or
>> Node.remove calls in between) should IMHO never fail with an
>> InvalidItemStateException.
>>
>> BR,
>>
>> Jukka Zitting
>



-- 
Alexander Klimetschek
alexander.klimetschek@day.com

Re: concurrent writes

Posted by Phil Weighill-Smith <ph...@volantis.com>.
I have a (perhaps dumb) question about one of the points raised in the
linked issue (JCR-1552):

https://issues.apache.org/jira/browse/JCR-1552?focusedCommentId=12592051#action_12592051

Here you state that creating a child node is like a SQL INSERT, whilst
setting a property is like a SQL UPDATE; the implication is that a node
is like a row and a property is like a column.

In that case, is it possible to set a property during the creation of a
node? If not, then surely setting a property the very first time should
be equivalent to a SQL INSERT - after all an INSERT allows all columns
to be assigned values during initial creation of the row; you are not
required to do both an INSERT and an UPDATE.

Or is it that the JCR API structure simply prevents an implementation
from handling this case (seems unlikely)? (Yes, I can see that it may
require the implementation to maintain additional internal state to
handle the case, but it seems doable.)

My concern is that whilst at the JCR level locking may be a nice and
easy solution this doesn't always fit well with clients; we have an
application using a non-JCR content repository that essentially does
optimistic locking; we allow any number of users to perform concurrent
viewing and/or editing of nodes and on save handle conflicts by allowing
automatic and (when needed) manual merges.

We are looking to leverage JCR and Jackrabbit in an updated version of
the application, so this behaviour is relatively important to us - it
needs to be clearly documented and consistent (plus, obviously,
conformant with the specification). I would think that we can work
around it either way with a combination of version detection and
short-term node locking during write.

Phil :n.

On Tue, 2009-01-06 at 10:17 +0100, Jukka Zitting wrote:

> Hi,
> 
> On Mon, Jan 5, 2009 at 2:16 PM, Torsten Curdt <tc...@apache.org> wrote:
> > Thanks! That links was very interesting ...not sure it gives a final
> > answer though.
> 
> Yeah, we never got around to going through the code based on the
> results of that discussion.
> 
> You may want to file a bug report about the setProperty behaviour. A
> set of concurrent setProperty calls (with no Node.addNode or
> Node.remove calls in between) should IMHO never fail with an
> InvalidItemStateException.
> 
> BR,
> 
> Jukka Zitting

Re: concurrent writes

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Mon, Jan 5, 2009 at 2:16 PM, Torsten Curdt <tc...@apache.org> wrote:
> Thanks! That links was very interesting ...not sure it gives a final
> answer though.

Yeah, we never got around to going through the code based on the
results of that discussion.

You may want to file a bug report about the setProperty behaviour. A
set of concurrent setProperty calls (with no Node.addNode or
Node.remove calls in between) should IMHO never fail with an
InvalidItemStateException.

BR,

Jukka Zitting

Re: concurrent writes

Posted by Torsten Curdt <tc...@apache.org>.
Thanks! That links was very interesting ...not sure it gives a final
answer though.

IMO it would be consistent if neither would fail

       Session s1 = ...
       Session s2 = ...
       String newPropName = Long.toString(System.currentTimeMillis());
       s1.getRootNode().setProperty(newPropName, "1");
       s2.getRootNode().setProperty(newPropName, "2");
       s1.save();
       s2.save();

       Session s1 = ...
       Session s2 = ...
       s1.getRootNode().setProperty("b", "0");
       s1.save();
       s1.getRootNode().setProperty("b", "1");
       s2.getRootNode().setProperty("b", "2");
       s1.save();
       s2.save();

at least not from my user's perspective. Unless you ask for such information.
Requiring a lock/transaction to prevent unexpected behavior sounds fair.

cheers
--
Torsten

Re: concurrent writes

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Mon, Jan 5, 2009 at 10:01 AM, Torsten Curdt <tc...@apache.org> wrote:
> Indeed that's what I meant. Let's assume A and B are both write to
> property "jcr:data" or something.

See https://issues.apache.org/jira/browse/JCR-1552 for a good
discussion about how such cases are and should be handled.

BR,

Jukka Zitting

RE: concurrent writes

Posted by 류대원 <dw...@nhncorp.com>.
Right. It throws javax.jcr.InvalidItemStateException!

Sorry for giving a wrong answer...

I was confused...^^;;

Normally use lock and transactions (node has to be lockable.)

- won

-----Original Message-----
From: tcurdt@vafer.org [mailto:tcurdt@vafer.org] On Behalf Of Torsten Curdt
Sent: Monday, January 05, 2009 6:01 PM
To: users@jackrabbit.apache.org
Subject: Re: concurrent writes

>> Let's say I have two people A and B editing a node from a JCR
>> repository. Both hold a reference to the node concurrently in
>> different sessions. Both modify some properties. Now A saves his
>> session, then B saves his session. IIUC the repository would now show
>> the state of B's session as B was essentially last. Assuming the node
>> has mixin mix:versionable I would expect to revisions like
>>
>> 1 original
>> 2 from A
>> 3 from B
>>
>> Are these assumptions correct?
>
> depends on what exactly you mean with 'some properties'. if the sets of modified
> properties from A and B overlap you get an InvalidItemStateException.

Indeed that's what I meant. Let's assume A and B are both write to
property "jcr:data" or something.

> See:
> http://www.day.com/specs/jcr/1.0/7.1.1.4_Invalid_States.html

Maybe I am just reading it wrong but I still don't think this is
precisely answering the question. For one it says "The altered item in
the Session remains and may be saved later" and then "Note that this
is precisely the same situation as would arise if a change were made
to a workspace through another Session. In both cases the save on this
Session may throw an InvalidItemStateException."

> versioning is a different story. if you want to be sure that a
> modify-item/version-item sequence works without an InvalidItemStateException
> then you need to lock the item before you modify it and finally unlock it after
> you versioned it.

Right. I am currently trying to figure out when/if I have to lock and what.

>> Would there be any sign/notification (exception/return code) for B
>> that the node he wants to write to was changed by A?
>
> yep, the above mentioned exception.

That's the exact opposite of what Won said :)

Seems like it is time for a test case.

cheers
--
Torsten



Re: concurrent writes

Posted by Torsten Curdt <tc...@apache.org>.
>> Let's say I have two people A and B editing a node from a JCR
>> repository. Both hold a reference to the node concurrently in
>> different sessions. Both modify some properties. Now A saves his
>> session, then B saves his session. IIUC the repository would now show
>> the state of B's session as B was essentially last. Assuming the node
>> has mixin mix:versionable I would expect to revisions like
>>
>> 1 original
>> 2 from A
>> 3 from B
>>
>> Are these assumptions correct?
>
> depends on what exactly you mean with 'some properties'. if the sets of modified
> properties from A and B overlap you get an InvalidItemStateException.

Indeed that's what I meant. Let's assume A and B are both write to
property "jcr:data" or something.

> See:
> http://www.day.com/specs/jcr/1.0/7.1.1.4_Invalid_States.html

Maybe I am just reading it wrong but I still don't think this is
precisely answering the question. For one it says "The altered item in
the Session remains and may be saved later" and then "Note that this
is precisely the same situation as would arise if a change were made
to a workspace through another Session. In both cases the save on this
Session may throw an InvalidItemStateException."

> versioning is a different story. if you want to be sure that a
> modify-item/version-item sequence works without an InvalidItemStateException
> then you need to lock the item before you modify it and finally unlock it after
> you versioned it.

Right. I am currently trying to figure out when/if I have to lock and what.

>> Would there be any sign/notification (exception/return code) for B
>> that the node he wants to write to was changed by A?
>
> yep, the above mentioned exception.

That's the exact opposite of what Won said :)

Seems like it is time for a test case.

cheers
--
Torsten

Re: concurrent writes

Posted by Marcel Reutegger <ma...@gmx.net>.
Torsten Curdt wrote:
> I am wondering how "concurrent" writes are handled with
> jcr/jackrabbit. While the spec (4.1.3.2 Transient Storage in the
> Session) does answer some of the questions I was wondering about some
> of the details.
> 
> Let's say I have two people A and B editing a node from a JCR
> repository. Both hold a reference to the node concurrently in
> different sessions. Both modify some properties. Now A saves his
> session, then B saves his session. IIUC the repository would now show
> the state of B's session as B was essentially last. Assuming the node
> has mixin mix:versionable I would expect to revisions like
> 
> 1 original
> 2 from A
> 3 from B
> 
> Are these assumptions correct?

depends on what exactly you mean with 'some properties'. if the sets of modified
properties from A and B overlap you get an InvalidItemStateException. See:
http://www.day.com/specs/jcr/1.0/7.1.1.4_Invalid_States.html

versioning is a different story. if you want to be sure that a
modify-item/version-item sequence works without an InvalidItemStateException
then you need to lock the item before you modify it and finally unlock it after
you versioned it.

> Would there be any sign/notification (exception/return code) for B
> that the node he wants to write to was changed by A?

yep, the above mentioned exception.

regards
 marcel