• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: EC locking/shared snapshots/old data saved
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: EC locking/shared snapshots/old data saved


  • Subject: Re: EC locking/shared snapshots/old data saved
  • From: ocs--- via Webobjects-dev <email@hidden>
  • Date: Fri, 29 May 2020 17:42:46 +0200

Jesse,

> On 29. 5. 2020, at 3:15 PM, Jesse Tayler <email@hidden> wrote:
> Well, I don’t know but I think the fact you’d be having this problem points
> to another problem.

Perhaps it does, but frankly, I can't see that.

> I don’t know your traffic or architecture, but you really should not have
> that problem at all, I wonder if perhaps you are creating too many separate
> ECs?

Not really. Unless I am missing something of importance (do please correct me
if so), the problem can happen whenever

(i) there are at least two different ECs;
(ii) through which different properties of same object are changed;
(iii) and, at least one EC is locked before changes and unlocked after saving
(otherwise, we'd get the possible solution (a));

in a multi-threaded environment (background threads,
WOAllowsConcurrentRequestHandling, or both).

> I find myself generally putting the bulk of operations into one EC and
> sometimes creating others for one-off stuff or just because it is a linear
> process with clear results.

Well each user would have normally his own EC in his own session; along with
WOAllowsConcurrentRequestHandling and standard EC locking that would be quite
sufficient to create the problem, I believe, far as (ii) and (iii) happen, too.
Normally with Wonder auto-locking (iii) does; as for (ii), it depends on the
code, but is pretty probable.

Background threads do not change the principle at all; they just might increase
the probability this happens if they lock their ECs, for they typically run for
much longer than R/R loop workers.

> Recently I did a lot of invalidating objects based on flags that were likely
> to require updating from a remote thread, this isn’t a conflict but I did
> need to ensure those objects were fetched and their contents written over
> what is in memory.
>
> In that case, the user operating the session was really the only part that
> needed instant updates and only in certain circumstances.

Well if your session user's code either updates the changes (through
unlock/lock? Or in antoher way? If so, how?) or does not make his own changes
(of other properties of the same object), or does not save after the thread
does, there's no problem I guess.

> Anyway, I’d think about the problem more broadly since I’m personally
> confident WO/Wonder has the most logical locking and EC handling that has
> been honed and crafter over decades and used in all kinds of situations.

I believe the root of the problem is the shared snapshot, which is a WO-level
quirk (understandable to save memory, but potentially leading to this pitfall).

> That confidence would lead me to at least try and solve your issues in
> another way perhaps

Perhaps, I'd be grateful for any reasonable way to solve it.

The (a) — shown in the test code below, too — still looks to me as a pretty
nice and easy solution; I just wonder why Wonder (sorry, couldn't resist) does
not do that automatically in ERXEC.saveChanges? Would it perhaps cause some
other grave problems which I can't see myself (but will be bit by them hard if
I try to do that myself in my own EC subclass)?

To better elucidate, it can be tested by a code similar to this (it's Groovy,
and a bit tweaked at that; but I believe readable and understandable enough — I
must admit in those years I use this infinitely better language I essentially
forgot how to write in pure Java and would take me a small eternity to re-write
into the darned thing :))

===
    WOComponent test(unlockEC) {
        eo.foo="new" // eo's some EO in defaultEC; assume string attributes
foo/bar, works with any property same way
        def entity=eo.entityName,key=eo.rawPrimaryKey // for simplicity. Works
with any way of fetching the object
        Thread.start { // thread just simulates another user changing 'bar' and
saving in his own EC of his own session
            ERXEC ec=ERXEC.newEditingContext() // locking here irrelevant:
neither harms nor helps in this case
            def obj=EOUtilities.objectWithPrimaryKeyValue(ec,entity,key)
            obj.bar="new"
            ec.saveChanges()
            println "thread: saved, foo is '$obj.foo' bar '$obj.bar'" // both
would be new; so far so good
        }
        Thread.sleep(100) // simulate just a bit slow processing of whatever
        if (unlockEC) { // this fixes the problem in a way of (a) mentioned
below
            eo.editingContext.unlock() // ... for here the changes from the
thread are merged-in
            eo.editingContext.lock()
        }
        eo.editingContext.saveChanges()
        println "saved, foo is '$eo.foo' bar '$eo.bar'" // if !unlockEC, bar
would be old, oops!
    }
    WOComponent test { test(NO) } // this action causes the problem (that after
all's done, bar's again the old one)
    WOComponent testUnlocking { test(YES) } // this sports the
possible-solution (a) and works properly
===

If you don't like the thread, precisely the same can be done with two actions —
one with the delay and the other without — triggered by two separate users from
two separate sessions with WOAllowsConcurrentRequestHandling set; it's the very
same principle, just a bit more work to set up and test :)

Thanks and all the best,
OC

>
>> On May 29, 2020, at 9:00 AM, OCsite via Webobjects-dev
>> <email@hidden> wrote:
>>
>> Hi there,
>>
>> just again, I've been bit in my tender parts by the well-known problem that
>>
>> 1. thread A locks its EC
>> 2. thread B saves some change into DB
>> 3. thread A saves its own changes (of different properties), which alas as a
>> side-effect also reverts B's changes ...
>>
>> ... since A's EC still contains the state before B's changes, and when that
>> state is compared with the shared snapshot (updated in step 2), the original
>> outdated object state before B's changes looks like a new change done by A
>> and thus is saved.
>>
>> Isn't there some general solution of this problem? I can think of at least
>> three:
>>
>> (a) always unlock (and immediately re-lock) EC before saving, preferably
>> directly in the ERXEC.saveChanges() code (resp. overridden saveChanges of my
>> own ERXEC subclass, set as er.extensions.ERXEC.editingContextClassName).
>> That, far as I understand, would merge all the other changes (of which EOF
>> already well knows due to the notifications, but it can't merge them whilst
>> the EC is locked).
>>
>> That would be pretty easy to do, but I am not sure of other dangers which it
>> possibly might bring? There could be plenty, I am afraid.
>>
>> (b) implement EC-based non-shared snapshots and use them instead of (or
>> rather along with) the shared ones to determine what to save into the DB.
>>
>> That would be considerably more work, again with possible dangers which I
>> can't quite see now.
>>
>> (c) invent a scheme with timestamps attached to individual properties in
>> shapshots and compare them, letting the newest win.
>>
>> Probably too much at the rube-goldbergish side to be practical.
>>
>> Has somebody already tried and tested either (a) or (b) or (c) or any other
>> approach, better than those three, to alleviate this kind of problems with a
>> success?
>>
>> Thanks,
>> OC
>> _______________________________________________
>> 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

References: 
 >EC locking/shared snapshots/old data saved (From: OCsite via Webobjects-dev <email@hidden>)
 >Re: EC locking/shared snapshots/old data saved (From: Jesse Tayler via Webobjects-dev <email@hidden>)

  • Prev by Date: Re: MacOS WebObjects Apache 2.4 Adaptor
  • Next by Date: Sign in with apple?
  • Previous by thread: Re: EC locking/shared snapshots/old data saved
  • Next by thread: Sign in with apple?
  • Index(es):
    • Date
    • Thread