• 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: relationship value different in another EC (was: ordered and filtered fault efficiency)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: relationship value different in another EC (was: ordered and filtered fault efficiency)


  • Subject: Re: relationship value different in another EC (was: ordered and filtered fault efficiency)
  • From: Ramsey Gurley <email@hidden>
  • Date: Tue, 17 Feb 2015 10:30:09 -0700

I think it would help you to explore the actual behavior of EOF before making too many more bad assumptions.

http://www.wocommunity.org/podcasts/wowodc/east09/WOWODC09E-EOEnterpriseObjects.mov

First watch the whole presentation. In that presentation, there’s a demo with an app called freshness explorer. You will probably be interested in running it locally. You can find a copy of it here

https://github.com/nullterminated/ponder/blob/master/ERR2d2w/Support/FreshnessExplorer.zip

I think you will find it enlightening. If you’d like to see sql transaction logging in freshness explorer, you need to direct it at a database instead of using Wonder's memory adaptor.


On Feb 17, 2015, at 6:00 AM, OC <email@hidden> wrote:

> On 16. 2. 2015, at 9:52, OC <email@hidden> wrote:
>
>> Nevertheless with the last valid thing I already took your advice and modelled it -- I dodged changing the DB for I was lucky and I happened to have in my model one legacy unused INTEGER attribute, which I used for a FK -- and preliminarily, it seems to work excellently.
>
> Alas, it does not when there are concurrent threads -- in that case, one of them can still contain the old value for the relationship, although I am locking the OSC :(
>
> My current code looks essentially like this:
>
> ===
>            EOEditingContext ec=auction.editingContext()
>            EOObjectStore osc=ec.rootObjectStore()
>            osc.lock()
>            try {
>              println "OLD: $auction.lastValidPriceOffer()" // now a modelled :1 relationship, auction contains FK
>              DBPriceOffer po=... new offer created and inserted to EC ...
>              println "ENCACHED: $po"
>              auction.setLastValidPriceOffer(po)
>              ec.saveChanges()
>            } finally {
>              println "NEW: $auction.lastValidPriceOffer()"
>              ocs.unlock()
>            }
> ===
>
> Now, I though this code is safe (single-instance, concurrent requests), but it is not. If the reqeusts come sequentially, it works perfectly, but with concurrent requests I am getting results like this
>
> === // WorkerThread5 and WorkerThread4 run concurrently
> # WorkerThread5 happened to lock first; WorkerThread4 waits all right
> 13:07:42.163|WorkerThread5 --- OLD <DBPriceOffer@2072296340 PK:1002835 Price:'888' by:'vilklient' /EC:1192846461>
> 17.2 13:07:42: ENCACHED: <DBPriceOffer@892254365 PK:null N Price:'887' by:'vilklient3' /EC:1192846461> [1]
>
> # ops logged in databaseContextWillPerformAdaptorOperations; note the new lastValidPriceOffer FK (1002836) _is_ stored properly in lvo_id (where it replaces the previous one, 1002835):
> - 1: INSERT on 'DBPriceOffer'  6{validOffer:true, uid:1002836, auction_id:1000755, price:887, creationDate:2015-02-17 12:07:42 Etc/GMT, creator_id:1000121}
> - 2: UPDATE on 'DBAuction' ((uid = 1000755) and (lvo_id = 1002835)) 1{lvo_id:1002836}
>
> # and just before unlocking, in this thread, lastValidPriceOffer is all right
> 13:07:42.235|WorkerThread5 --- NEW <DBPriceOffer@892254365 PK:1002836 Price:'887' by:'vilklient3' /EC:1192846461>
>
> # since WorkerThread5 did save all right and did unlock the OSC, WorkerThread4 starts -- and oops, it still has the wrong old value of lastValidPriceOffer! [2]
> 13:07:42.246|WorkerThread4 --- OLD: <DBPriceOffer@746572082 PK:1002835 Price:'888' by:'vilklient' /EC:1851717404> prc 888 au.cpc 888
>
> # from now on, of course it's all wrong. Nevertheless it is interesting that the thread _does know_ the _new_ value of lvo_id (1002836), and thus saves the wrong offer! [3]
> - 1: INSERT on 'DBPriceOffer'  6{validOffer:true, uid:1002837, auction_id:1000755, price:887, creationDate:2015-02-17 12:07:42 Etc/GMT, creator_id:1000049}
> - 2: UPDATE on 'DBAuction' ((uid = 1000755) and (lvo_id = 1002836)) 1{lvo_id:1002837}
> ===
>
> I must admit I am (just again) somewhat surprised.
>
> I rather presumed saveChanges would make sure values of all EOs (including the relationships) in all ECs in the same instance with just one OSC are consistent, and thus I would at [2] get the right value of lastValidPriceOffer -- the one stored (in another thread) before at [1], and successfully saved there.
>
> I considered there's a possibility I am wrong, and the EC's will not get synced properly, and I will still get the old value of lastValidPriceOffer at [2] -- but in that case I thought the auction itself in the same EC of the same thread would also contain the old FK value in its 'lvo_id', and since it is a locking attribute, I will get an optimistic locking fail, and the wrong value will not be saved at [3].
>
> I must admit I can't really see how it is possible the disastrous combination of
> - the auction contains the _new_ foreign key;
> - at the same moment, the relationship returns the _old_ object?!?
>
> Note that it looks like some caching issue, for the problem never happens when saving is not concurrent. If the first thread's R/R loop finishes before the latter ones' starts, the relationship is consistent with the foreign key.
>
> Is this normal EOF behaviour, or does it indicate another weird problem in my app?
>
> And even more important -- how to fix it? What am I to do at the start/end of the OSC-locked critical section, so as I am sure that the FK stored inside the object and the relationship modelled on it are consistent?
>
> Thanks a big lot!
> OC
>
> === The relationship definition in the model plist:
> 		{
> 			deleteRule = EODeleteRuleDeny;
> 			destination = DBPriceOffer;
> 			isToMany = N;
> 			joinSemantic = EOInnerJoin;
> 			joins = (
> 				{
> 					destinationAttribute = "uid";
> 					sourceAttribute = lvo_id;
> 				},
> 			);
> 			name = lastValidPriceOfferCache;
> 		},
> ===
>
> === The code used to access the relationship:
>    public DBPriceOffer lastValidPriceOffer {
>        def cached=this.lastValidPriceOfferCache()
>        if (cached) return cached
>        ... legacy code to search for it for old auctions ...
>    }
>    DBPriceOffer lastValidPriceOfferCache() {
>        storedValueForKey('lastValidPriceOfferCache')
>    }
> ===
>
>
> _______________________________________________
> 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


  • Follow-Ups:
    • Re: relationship value different in another EC (was: ordered and filtered fault efficiency)
      • From: OC <email@hidden>
References: 
 >ordered and filtered fault efficiency (From: OC <email@hidden>)
 >Re: ordered and filtered fault efficiency (From: Chuck Hill <email@hidden>)
 >Re: ordered and filtered fault efficiency (From: OC <email@hidden>)
 >Re: ordered and filtered fault efficiency (From: Chuck Hill <email@hidden>)
 >Re: ordered and filtered fault efficiency (From: OC <email@hidden>)
 >relationship value different in another EC (was: ordered and filtered fault efficiency) (From: OC <email@hidden>)

  • Prev by Date: relationship value different in another EC (was: ordered and filtered fault efficiency)
  • Next by Date: Re: relationship value different in another EC (was: ordered and filtered fault efficiency)
  • Previous by thread: relationship value different in another EC (was: ordered and filtered fault efficiency)
  • Next by thread: Re: relationship value different in another EC (was: ordered and filtered fault efficiency)
  • Index(es):
    • Date
    • Thread