NEXTSTEP

Title: Using Oracle NOWAIT Locks with EOF 

Entry Number: 
Last Updated: Feb 20 1995
Document Revision:

Keywords: EOF, adaptor, Oracle, lock, NOWAIT, pessimistic, EOUpdateWithPessimisticLocking, setUpdateStrategy:

Question

Q:  EOF provides the ability to use pessimistic locks by sending EOUpdateWithPessimisticLocking to EODatabaseContext's setUpdateStrategy: method.  However if client A has the pessimistic lock and  client B tries to access the locked row(s), client B blocks until client A releases the lock.

Oracle 7 supports "NOWAIT" locks which allows client B in this scenario to return immediately after failing to get the lock, allowing it to present an error message or otherwise handle the situation.  Is this supported in EOF?

Answer

A:  Although this feature is not explicitly supported in the EOF 1.1 Oracle7 adaptor, it is very easy to add.  The only difference between getting a pessimistic lock and a NOWAIT pessimistic lock is the NOWAIT keyword appended to the end of the SELECT clause that gets the lock.  This functionality can be added in an EOAdaptorChannel delegate with the following code.  (This object needs to be the delegate of both the EOAdaptorChannel and EOAdaptor; this can be set up in awakeFromNib).

#import <eoaccess/eoaccess.h>

@interface ExampleNOWAITDelegate
{
	BOOL locking;
}

@end

@implementation ExampleNOWAITDelegate

- (EODelegateResponse)adaptorChannel:channel
    willSelectAttributes:(NSMutableArray *)attributes
    describedByQualifier:(EOQualifier *)qualifier
    fetchOrder:(NSMutableArray *)fetchOrder
    lock:(BOOL)flag
{
   locking = flag;
   return EODelegateApproves;
}

- (EODelegateResponse)adaptorChannel:channel
    willEvaluateExpression:(NSMutableString *)expression
{
    if (locking && [self useNOWAIT])
        [expression appendString:@" NOWAIT"];

    return EODelegateApproves;
}

- (BOOL)adaptor:(EOAdaptor *)adaptor
    willReportError:(NSString *)error
{
    /*
     *  error is the error message provided by the adaptor; if it begins
	 *  with "ORA-00054:", the resources that we want to lock are busy.
     *  Here we just call NSLog(), but ultimately we should provide an
     *  alert panel for the user or otherwise handle this.
     */
    if([error hasPrefix:@"ORA-00054:"]) {
        NSLog(@"NOWAIT resources busy!\n");  // Should act accordingly
        return NO;
    }

    return YES;
}

- (void)adaptorChannel:channel
    didEvaluateExpression:(NSString *)expression
{
    locking = NO;
}
@end

Valid for: EOF 1.0, EOF 1.1, NEXTSTEP 3.2 Developer, NEXTSTEP 3.3 Developer