RE: Concurrency question
RE: Concurrency question
- Subject: RE: Concurrency question
- From: "Ruenagel, Frank" <email@hidden>
- Date: Thu, 2 Aug 2007 16:48:41 +0200
- Thread-topic: Concurrency question
Hi,
perhaps worth noting here that this issue is rather old and regulary pops up in the list
for years now. See the presentation from M.Crawford from 2002:
http://conferences.oreillynet.com/presentations/macosx02/crawford_eoconflicts.pdf
AFAIK there is no good solution (except different EOF-Stacks).
In some cases we worked around the problem with comparing
snapshots. If a user opens a form the committedSnaphot of the data
is cached in a dictionary. If the user makes a ec.saveChanges() we compare
the cached dictionary with the values of the current committedSnapshotForObject.
If there are diffs, any other user meanwhile has changed the data.
In a sense we compare the "expected" committedSnapshotForObject
with the "current" committedSnapshotForObject.
But this workaround is far from being perfect....
Happily the problem does not rise up very often.
Regards
FR
> -----Original Message-----
> From: webobjects-dev-bounces+webobjects=email@hidden
> [mailto:webobjects-dev-bounces+webobjects=symposion.de@lists.a
> pple.com]O
> n Behalf Of Oliver Egger
> Sent: Thursday, August 02, 2007 2:36 PM
> To: Mike Schrag; Development WebObjects
> Subject: Re: Concurrency question
>
>
> hi mike
>
> what you are describing here relieves my heart! back in february
> (https://sourceforge.net/mailarchive/message.php?msg_id=ce7f98
> email@hidden)
> i tried to argue why i needed a seperate osc because i was having the
> "blow-away-other-changes-in-the-EO" effect but couldn't
> explain it so detailed
> as you did and didn't even think i would meet once a EOF bug ....
>
> thanks a lot for that detailed description!
> oliver
>
> On 8/2/07, Mike Schrag <email@hidden> wrote:
> > My reply was too big with the attachments, so I moved my response
> > into the wiki:
> >
> > http://wiki.objectstyle.org/confluence/display/WO/
> > Programming__WebObjects-EOF-Using+EOF-Problems
> >
> > The last one, "Strange Locking Problems" ... And for the lazy:
> > It would appear that there is, in our opinion, some bugs related to
> > optimistic locking within a single EOF stack. Essentially what it
> > boils down to is that it appears that the update database operation
> > that is created as a result of a call to .saveChanges() is backed by
> > the EODatabaseContext snapshot and NOT the "working" snapshot inside
> > in the EO in the editing context it came from. What this means is
> > that while changes are not merged until you .unlock() and .lock()
> > under normal circumstances, because the underlying snapshot that EOF
> > diffs your changes against on save is the DBC snapshot, it's
> > effectively inadvertently "merged" on commit. That is to say that if
> > another EC makes changes and saves, then you make different changes
> > and save, you will blow away their changes with no sign of an
> > optimistic locking exception because your snapshot IS their snapshot
> > now (meaning, it looks like just you are overwriting their changes,
> > versus the reality of the situation that you are actually
> conflicting
> > with their changes). After discussing this some, we believe that if
> > the update operation used a version of the EO's backing snapshot
> > instead that these weird behaviors would be fixed and it
> would behave
> > exactly like a normal conflicting update if you were in two EOF
> > stacks. The current behavior smells of bug, but I'm curious
> if anyone
> > a dissenting opinion on the topic. It's certainly really complicated
> > and nasty down in that code, so it's possible there's some crazy
> > justifiable reason for it.
> >
> > Go to the wiki for the diagrams.
> >
> > ms
> >
> > On Aug 2, 2007, at 1:12 AM, Chuck Hill wrote:
> >
> > > The problem comes in when the modifications are made and saved
> > > after your editing context has been locked in the RR loop. I
> > > tricked ;-) Mike into looking at this today with. Looks like
> > > tigers lurk here. Maybe Mike will comment.
> > >
> > >
> > > Chuck
> > >
> > >
> > > On Aug 1, 2007, at 2:34 PM, Pierre Bernard wrote:
> > >
> > >> You can simulate OL, by listening to merge notifications. If it
> > >> affects a modified object you can later on refuse to save.
> > >>
> > >> Pierre
> > >>
> > >>
> > >> On Aug 1, 2007, at 7:18 PM, Chuck Hill wrote:
> > >>
> > >>>
> > >>> On Aug 1, 2007, at 5:00 AM, Miguel Arroz wrote:
> > >>>
> > >>>> Hi!
> > >>>>
> > >>>> The contexts are locked. The problem is that it's
> not the same
> > >>>> context - it's a different context per thread, with
> local copies
> > >>>> of the same objects.
> > >>>>
> > >>>> Synchronizing solves the sample problem, but as my real
> > >>>> problem is much more complex than this example, it
> starts to get
> > >>>> a little... ugly. Also, I still did not full
> understand why, the
> > >>>> objects in the thread that runs in second are not updated with
> > >>>> the data saved by the thread that run first. I suspect that the
> > >>>> cause of this is that the objects only receive the
> notifications
> > >>>> to update themselves after finishing the R-R. Can
> anyone confirm
> > >>>> this?
> > >>>
> > >>> Yes, if you are locking properly (and I know you are), the
> > >>> changes only get merged at the end of the RR loop. You
> can do it
> > >>> yourself by unlocking and relocking the EC.
> > >>>
> > >>>
> > >>>> About being solving 2 different problems or not, it
> depends on
> > >>>> the level os abstraction you use to look at it. :)
> From my point
> > >>>> of view, I'm solving one problem - the problem of concurrent
> > >>>> updates. My app has now enough info to solve the problem (OL
> > >>>> fields, and how to retry). It would work *if* the UPDATE WHERE
> > >>>> data was fetched from the original data in the context, and not
> > >>>> in the row data.
> > >>>
> > >>> It gets more complex than this. One quick fix is to
> have each EC
> > >>> in its own EOF stack. But that can be rather memory expensive.
> > >>>
> > >>> Chuck
> > >>>
> > >>>
> > >>>
> > >>>> On 2007/08/01, at 03:03, Ken Anderson wrote:
> > >>>>
> > >>>>> Miguel,
> > >>>>>
> > >>>>> Is your editing context locked before calling incrementIt() ?
> > >>>>> I would think that would solve your concurrencyssue her
> > >>>>>
> > >>>>> If not, just synchronizing the method should solve the
> > >>>>> problem. It may seem inelegant, but you really ARE solving 2
> > >>>>> different problems...
> > >>>>>
> > >>>>> Ken
> > >>>>>
> > >>>>> On Jul 31, 2007, at 7:41 PM, Miguel Arroz wrote:
> > >>>>>
> > >>>>>> Hi!
> > >>>>>>
> > >>>>>> I'm trying to understand what's the best way to do
> something
> > >>>>>> here.
> > >>>>>>
> > >>>>>> Imagine that I need to get a object from the database,
> > >>>>>> modify some attribute based on itself and save it again.
> > >>>>>>
> > >>>>>> So, we have the method:
> > >>>>>>
> > >>>>>> public void incrementIt() {
> > >>>>>> if( aIsEven() ) { // 1
> > >>>>>> setB( b() + 1 ); // 2
> > >>>>>> }
> > >>>>>> setA( a() + 1 ); // 3
> > >>>>>> editingContext.saveChanges(); // 4
> > >>>>>> }
> > >>>>>>
> > >>>>>> Well, it's easy to solve the problem of update conflicts
> > >>>>>> between two different instances of the app. Just tick the OL
> > >>>>>> lock for a and b fields, catch the evil expression, refault
> > >>>>>> the object, and recalculate (and retry to save).
> That's "easy".
> > >>>>>>
> > >>>>>> Now, my problem is inside the same instance! Imagine that
> > >>>>>> this method runs at the same time and we have the following
> > >>>>>> run order, for threads X and Y, with the same object in two
> > >>>>>> different contexts (and imagine a = 3):
> > >>>>>>
> > >>>>>> X 1
> > >>>>>> Y 1
> > >>>>>> X 3
> > >>>>>> X 4
> > >>>>>> Y 3
> > >>>>>> Y 4
> > >>>>>>
> > >>>>>> This will produce wrong results, but it won't cause any
> > >>>>>> locking exception. Why?
> > >>>>>>
> > >>>>>> 1) Both threads get the object with a = 3.
> > >>>>>> 2) Both threads do not run line 2 because 3 is not even.
> > >>>>>> 3) The thread X increments a, and saves it. When
> saving, the
> > >>>>>> object at thread Y will have it's 'a' attribute updated,
> > >>>>>> assuming both objects are in the same coordinator.
> > >>>>>> 4) The thread Y increments a again, and saves it. N
> > >>>>>> optimistic locking exception will be thrown, because the
> > >>>>>> coordinator snapshot was updated in the last commit, so the
> > >>>>>> SELECT FOR UPDATE will run OK.
> > >>>>>>
> > >>>>>> This will cause a to be 5, but b did not increment as it
> > >>>>>> should. The problem is that, when saving, we are basing OL on
> > >>>>>> the row snapshot (that is updated during the process) and not
> > >>>>>> to the original value of the object when it was loaded into
> > >>>>>> the editing context.
> > >>>>>>
> > >>>>>> Well, this may be solved using the "classic" Java
> > >>>>>> "syncronized" stuff, and locks and all that stuff.
> But this is
> > >>>>>> a bit stupid. I already solved the problem with OL for the,
> > >>>>>> theoretically, more difficult case of managing several app
> > >>>>>> instances. Do I have to solve it all over again, in a
> > >>>>>> different way, to deal with multiple updates on the same
> > >>>>>> instance? Isn't there a way to use OL just like I'm already
> > >>>>>> doing?
> > >>>>>>
> > >>>>>> Yours
> > >>>>>>
> > >>>>>> Miguel Arroz
> > >>>>>>
> > >>>>>> Miguel Arroz
> > >>>>>> http://www.terminalapp.net
> > >>>>>> http://www.ipragma.com
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>> _______________________________________________
> > >>>>>> Do not post admin requests to the list. They will be ignored.
> > >>>>>> Webobjects-dev mailing list
> (email@hidden)
> > >>>>>> Help/Unsubscribe/Update your Subscription:
> > >>>>>>
> > >>>>>> 40anderhome.com
> > >>>>>>
> > >>>>>> This email sent to email@hidden
> > >>>>>
> > >>>>
> > >>>> Miguel Arroz
> > >>>> http://www.terminalapp.net
> > >>>> http://www.ipragma.com
> > >>>>
> > >>>>
> > >>>>
> > >>>> _______________________________________________
> > >>>> Do not post admin requests to the list. They will be ignored.
> > >>>> Webobjects-dev mailing list
> (email@hidden)
> > >>>> Help/Unsubscribe/Update your Subscription:
> > >>>> 40global-village.net
> > >>>>
> > >>>> This email sent to email@hidden
> > >>>>
> > >>>
> > >>> --
> > >>>
> > >>> Practical WebObjects - for developers who want to increase their
> > >>> overall knowledge of WebObjects or who are trying to solve
> > >>> specific problems.
> > >>> http://www.global-village.net/products/practical_webobjects
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> _______________________________________________
> > >>> Do not post admin requests to the list. They will be ignored.
> > >>> Webobjects-dev mailing list
> (email@hidden)
> > >>> Help/Unsubscribe/Update your Subscription:
> > >>>
> >>> email@hidden
> >>>
> >>> This email sent to email@hidden
> >>
> >> - - -
> >> Houdah Software s. à r. l.
> >> http://www.houdah.com
> >>
> >> HoudahGeo: One-stop photo geocoding
> >> HoudahSpot: Powerful Spotlight frontend
> >>
> >>
> >>
> >>
> >
> > --
> >
> > Practical WebObjects - for developers who want to increase their
> > overall knowledge of WebObjects or who are trying to solve specific
> > problems.
> > http://www.global-village.net/products/practical_webobjects
> >
> >
> >
> >
> >
> > _______________________________________________
> > Do not post admin requests to the list. They will be ignored.
> > Webobjects-dev mailing list (email@hidden)
> > Help/Unsubscribe/Update your Subscription:
> > 40mdimension.com
> >
> > This email sent to email@hidden
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden