Re: Lock nowait??
Re: Lock nowait??
- Subject: Re: Lock nowait??
- From: email@hidden
- Date: Sat, 31 Jul 2004 22:49:12 -0700
Hi,
I eventually got the lock nowait code to work as follows:
I created an object called LockController. The object has a single
method called lockNowait() which takes an EO as an argument.
The LockController builds an EOSQLExpression that can be used to select
the primary key of the EO. However, this EOSQLExpression does not have
the "FOR UPDATE NOWAIT" clause needed at the end in order to lock the
object. So what I do is create a new EOSQLExpression from this one as
follows:
EOSQLExpression lockExpression = factory.expressionForEntity(entity);
lockExpression.setStatement(selectExpression.statement() + " FOR
UPDATE NOWAIT");
NSDictionary binding =
(NSDictionary)selectExpression.bindVariableDictionaries().lastObject();
lockExpression.addBindVariableDictionary(binding);
Then the lock controller uses the EOAdaptorChannel's
evaluateExpression() method to execute the lock expression built. But
before that the LockController sets itself as the delegate of the
adaptor context and the editing context of the EO. That way, the
LockController receives the adaptorContextShouldCommit() message which
returns false. This way, the transaction stays open after calling the
evaluateExpression() and fetching the results.
If the lock expression fails to lock the object in the database then an
exception will be thrown when the evaluateExpression() method is
called. The lock controller simply catches the exception and return
false to indicate that we were not able to grab the lock.
If the lock is grabbed the lock controller returns true.
The LockController class is used as follows:
if (LockController.lockNowait(eo)) {
// Process the eo
...
// Save changes made and release the lock
eo.editingContext().saveChanges();
}
The last line where we invoke eo.editingContext().saveChanges() causes
the delegate notification message editingContextWillSaveChanges() to be
sent to the LockController. The lock controller then takes note and
the next time the adaptorContextShouldCommit() method is called it
returns true allowing the transaction to finally commit, thereby
releasing the database lock on the object.
Sorry I can't share the actual code. I don't own it. But this should
give you an idea of how to get it done.
Thanks to all who responded with ideas,
Ricardo Parada
System Architect
Medical Present Value, Inc.
On Jul 30, 2004, at 11:25 AM, Frangois Frisch wrote:
> if you use EOAdaptorChannel and open the channel yourself then EOF
> will wait till you close it manually
>
> something like
>
> this.adaptorChannel().openChannel();
> this.adaptorChannel().adaptorContext().beginTransaction();
>
> and then
> this.adaptorChannel().adaptorContext().commitTransaction();
> this.adaptorChannel().closeChannel();
>
> more info in
> http://www.wodev.com/cgi-bin/WebObjects/WODev?
> wikiPage=LowCostFetchesAndInserts
>
>
> Frangois
>
> sPearCat Lead Developer
> ----------------------
> sPearCat Web Catalogs
> http://www.spearcat.com
>
>
> On Jul 30, 2004, at 9:43 AM, email@hidden wrote:
>
>>
>> On Jul 30, 2004, at 9:16 AM, Chuck Hill wrote:
>>
>>> People have reported seeing SELECT FOR UPDATE issues when there was
>>> a value type error in the model. So this is at least possible. :-)
>>> I've never used it, but there is some way to tell EOF to use
>>> pessimistic locking, which is what select for update is.
>>>
>>> Why do you need the select for update? Is there another way to
>>> accomplish this?
>>
>> Basically, there's a table where each record represents a work unit.
>>
>> Processing such a record takes some time. There are a number of
>> agents or processes that read the records from the table. The
>> processes lock the record using ORACLE's "select for update nowait".
>> If successful then the process starts working on the locked record.
>> If unsuccessful then it means that some other process is already
>> working on it. The record is skipped and it moves to the next one.
>>
>> What is nice about ORACLE's nowait is that it tells you right away.
>> In addition, if the process dies for whatever reason the lock is
>> released by ORACLE.
>>
>> This is basically one way to balance the work load across the running
>> processes.
>>
>> As far as another way to accomplish this... Yes, this can be
>> accomplished in a different way. But the current design uses
>> ORACLE's nowait. :-)
>>
>> I got EOF to generate the SQL to do the "select from table_name where
>> record_id = ? for update nowait". However, EOF commits the
>> transaction right away when I fetch the result from this select
>> thereby releasing the lock. I need EOF to keep the transaction open
>> until it commits.
>>
>> I'm playing with the adaptor context delegate to see if I can have it
>> keep the transaction open.
>>
>> Thanks Chuck,
>>
>> Ricardo Parada
>>
>> _______________________________________________
>> WebObjects-dev mailing list
>> email@hidden
>> http://www.omnigroup.com/mailman/listinfo/webobjects-dev
_______________________________________________
webobjects-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/webobjects-dev
Do not post admin requests to the list. They will be ignored.