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 protected]> wrote: > On 16. 2. 2015, at 9:52, OC <[email protected]> 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 protected]) > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/webobjects-dev/rgurley%40smarthealth.com > > This email sent to [email protected] _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list ([email protected]) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to [email protected]
