Re: Never save objects which don't pass a test (was: searching for a weird deletion)
Re: Never save objects which don't pass a test (was: searching for a weird deletion)
- Subject: Re: Never save objects which don't pass a test (was: searching for a weird deletion)
- From: OC <email@hidden>
- Date: Fri, 20 Feb 2015 20:09:49 +0100
Chuck,
On 20. 2. 2015, at 19:37, Chuck Hill <email@hidden> wrote:
>> Actually _this_ should not be weird, this should be quite a normal code; the only requirement is that check-and-save, i.e., conceptually,
>> === [1]
>> if (TEST(eo.someRelationship().someAttribute(),newAttributeValue)) {
>> def new=EOUtilities.createAndInsertInstance(eo.editingContext(),'SomeRelationshipTarget')
>> new.someAttribute=newAttributeValue
>> eo.editingContext().saveChanges()
>> }
>> ===
>> so that I can be absolutely sure that nobody stores an attribute value which -- at the moment of COMMITTing the appropriate INSERT -- would not pass the TEST
...
>>> I believe that is the only way to absolutely ensure this. I don’t think you can make a rock-solid guarantee from the app code level.
>>>
>> Can't I? That's bad.
>>
>> So far, I thought this very simple concept should be rock-solid, but probably I am overlooking something of importance, as so often:
>>
>> === eo's entity locks on the someRelationship FK (among others) ===
>> OSC.lock() // possibly superfluous; simplifies situation by serializing intra-instance
>> try {
>> ec.unlock(); ec.lock() //* to make sure we get changes from other ECs now, by your excellent advice
>> def rel=eo.someRelationship() // in DB there might be a newer value (saved meantime by another instance)...
>> def attr=rel.someAttribute() // ... but it is not possible that in DB is an _older_ value than this
>> if (TEST(attr,newAttributeValue)) {
>> def new=EOUtilities.createAndInsertInstance(eo.editingContext(),'SomeRelationshipTarget')
>> new.setSomeAttribute(newAttributeValue) // once set, I NEVER change this value
>> eo.addObjectToBothSidesOfRelationshipWithKey(new,'someRelationship')
>> eo.editingContext().saveChanges() // catching optimistic exceptions and repeating the process if they happen
>> }
>> } finally {
>> OSC.unlock()
>> }
>> ===
>>
>> My reasoning is that
>> - intra-instance, consistency is ensured by locked (single) OSC and by //* -- I am sure that I see the latest eo.someRelationship and its rel.someAttribute before saving, and thus the TEST is reliable; my own instance, even with concurrent requests, can't do anything wrong
>> - inter-instance, the optimistic locking based on someRelationship FK should prevent saving in case any other instance succeeded to save its own new attribute meantime.
>>
>> What am I overlooking, how can this pattern fail?
>>
> I am not quite following the requirements. Is it unique only for this object or for all objects?
Sorry I have mislead you by using the term “UNIQUE“. It does not have to be unique; it must pass a slightly more complex test than uniqueness:
- when inserted into PRICE_OFFERS table,
- the newly inserted object must have value in column PRICE, which is higher,
- than any (max) of the already existing objects in that table, which
- have YES in a boolean column VALID, and
- at the same moment, have same value in AUCTION_ID column as the inserted object.
(In fact the real condition is even more complex, but this is the gist of it: consider an auction system, where a new bid added to a particular auction must be higher than all previous valid bids for the same auction.)
Nevertheless, I believe that when we are pursuing the implement-the-behaviour-at-the-application-level way (unlike the check restraint at the DB level), the particular TEST is actually irrelevant. The gist is that it must not be possible to store an object which does not pass TEST -- whatever the TEST tests.
See please again the [1] above -- the code must make sure that
(a) when TESTing, the participating objects are a proper snapshot of database contents of some moment in the past
(b) when saving, the code must make sure that if the values of the snapshot did change, the saving won't happen
That should be sufficient, should it not?
Does it make sense?
Thanks a lot,
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