Thanks a lot, but at the moment and in the hurry I would slightly prefer

(a) the information whether it is normal for EOF to contain at the same moment 
updated value of FK and stale value of a relationship in the same EC;
(b) if so, what's the best way to make them consistent.

(Truth is, for all those 20-odd years I am using EOF without any bigger problem 
I have always used the default setting of WOAllowsConcurrentRequestHandling=NO, 
and thus I indeed am pretty inexperienced with this, alas.)

Thanks again,
OC
 
On 17. 2. 2015, at 18:30, Ramsey Gurley <[email protected]> wrote:

> 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]

Reply via email to