Hello there,

I might be missing some important point, but I understand that

(a) editing context, while locked, does not update its registered objects
(b) session's default EC gets automatically locked at the start of the R/R 
loop, unlocked at the end
(c) the underlying (and shared) snapshots are updated whenever any EC saves to 
the DB.

Is it indeed so?

I, as always, am probably overlooking something of importance, but it seems to 
me this approach can work reliably with WOAllowsConcurrentRequestHandling=NO 
only. Correct me please if I am wrong, but it seems to me as soon as I switch 
WOAllowsConcurrentRequestHandling=YES, without adding some extra tricks/OSC 
locking/something like that to _each_ saveChanges, the following scenario can 
always happen:

(i) request A in thread A starts processing, locks its ECa
(ii) request B in thread B starts processing, locks its ECb

(iii) request A changes some important value, say, "auction.auctionDidEnd=new 
NSTimestamp()"
- it changes more things appropriately, e.g., it creates an audit record, etc.
- and it calls ECa.saveChanges() -- all the changes are committed to the 
database all right, shared shapshots get updated properly

(iv) request B makes some unimportant change, say, "auction.greeting='hi'"
- and it calls ECb.saveChanges()

At this moment, ECb compares values in its auction object (which does not know 
about the (iii) yet, for its ECb is locked and thus does not update) to the 
snapshot (which, contrariwise, has been updated in (iii) when ECa did save), 
and based on that generates essentially the following SQL:

===
UPDATE auctionTable
SET
  greeting='hi',     ## (1)
  auctionDidEnd=NULL ## (2)
WHERE
  auctionDidEnd=<the timestamp of (iii), got from the snapshot> ## (3)
  AND greeting=<any sweet previous value> 
===

(1) is the presumed behaviour, we made the change in (iv). Surprising though is 
(2), we did not make the change -- but it does happen, for (a) the auction EO 
in ECb contains NULL for auctionDidEnd (it has not been updated, for the EC is 
locked), and (b) at the same time, the shared snapshot has been updated by the 
save at (iii), and contains a non-null timestamp for that attribute -- and 
therefore EOF will generate the appropriate SET.

The optimistic locking won't help, for again, the shared shapshot has been 
updated and contains the timestamp stored at (iii); therefore the WHERE would 
look like (3) and the COMMIT will happily save the changes.

Which means the business model got terribly inconsistent: the auction did end 
at (iii), it was duly audited and perhaps it caused lots of other changes; but 
in (iv), it has been blindly re-surrected due to (2)!

Now, of course, it's again a similar case to multi-instanceness: if one writes 
the application from scratch with concurrency on mind, it's comparatively easy 
to prevent. Nevertheless, I don't know of you, but with my code it simply is 
not the case; there is heaps of legacy code, written years ago, when nobody 
ever considered multi-instanceness or concurrent request handling.

It sort of seems to me this is a cul-de-sac: without a serious rewrite, there 
simply is no way at all to use legacy code with concurrent request handling or 
multi-instance: as soon as that happens, there is _always_ a danger of grave 
inconsistencies.

Or am I missing some nice tricks here?

Thanks a lot for any insight,
OC


 _______________________________________________
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