This direct action is running on an application that has around 20
instances running. So some how one of the other instances is inserting
a new keyword and the other instances continue to report it as not
being there.


You could have a race condition where two instances check the database for the same keyword, and see that it is not there.  They they both insert it.  The second one to commit will (attempt to) duplicate the value in the database.  Is that what you are seeing?  You can even see this on a single instance if you are dispatching requests concurrently.

It is highly probable that this is what's happening.  It should not have anything to do with stale data because the keywords are new.  For others on the list; I was involved in the development of this system and know the entire process and how it's written.

Transaction rate on this table is very high (somewhere in the 25-30 req./sec. range) so race conditions would be very likely.

The only solution I can think of would be to recover from the error, instead of trying to prevent it.  Basically let the race condition occur, catch the exception, then perform a second request to get the keyword inserted by the other instance/request.  Another option would be to lock the entire table (which is NOT feasible).  The recovery request should use  fs.setRefreshesRefetchedObjects(true) where fs is the EOFetchSpecification used for the search.  I'm pretty sure this code is already doing that,  which again is an indication that is this NOT a stale data issue.


Here is the scenario:

Instance 1:
SELECT:
RESULT:
- DVDs
- CDs
- Music
- Books

Instance 2:
SELECT:
RESULT:
- DVDs
- CDs
- Music
- Books

Instance 1:
INSERT
- Audio Books

Instance 2:
INSERT
- Audio Books
EXCEPTION
- Duplicate value in unique index
SELECT
- Audio Books

On Dec 2, 2005, at 1:45 PM, Chuck Hill wrote:

Hi Eric,

I am not sure that I am following this correctly, so some questions below.


On Dec 2, 2005, at 8:26 AM, Eric Stewart wrote:

Hello everyone,

I'm having a problem where it appears I'm getting stale data from the
editing context.

I have a direct action that is inserting keywords into a database
table. The word itself (called "descriptor") is unique because I don't
want the same keyword in the system twice.

When a direct action request comes in for information about that
keyword, I check to see if that keyword is already in the system. If
not I add it.

Here is the code I use to check for that keyword.

/**
* Determines whether a new keyword with the given descriptor is
present in the system.
*/
public static boolean isPresentByDescriptor(EOEditingContext ec,
String descriptor) {
NSDictionary args = new NSDictionary(descriptor, "descriptor");
EOQualifier qual = EOQualifier.qualifierToMatchAllValues(args);
EOFetchSpecification fs = new EOFetchSpecification("NewKeyword", qual, null);


// Make sure we fetch fresh data
fs.setRefreshesRefetchedObjects(true);


// Find the keyword matching value
NSArray keywords = ec.objectsWithFetchSpecification(fs);
if (keywords.count() == 0) {
// No match found
return false;
} else if (keywords.count() > 1) {
// More than one match found
if (NSLog.debugLoggingAllowedForLevel(NSLog.DebugLevelCritical)) {
NSLog.debug.appendln("Duplicate new keyword found matching: " + descriptor);
}
return true;
} else {
// Match found return the keyword
return true;
}
}

What is happening is I'm getting a lot of exceptions complaining that
a keyword being added to the system is not unique, hence I can only
guess that data from the EC is stale and is not reflecting newly
inserted keywords.

By exception do you mean the debug message above, a unique constraint violation on the database, or something else?



This direct action is running on an application that has around 20
instances running. So some how one of the other instances is inserting
a new keyword and the other instances continue to report it as not
being there.


You could have a race condition where two instances check the database for the same keyword, and see that it is not there.  They they both insert it.  The second one to commit will (attempt to) duplicate the value in the database.  Is that what you are seeing?  You can even see this on a single instance if you are dispatching requests concurrently.


Should I be using EditingContext.refaultAllObjects() or will this not
solve my problem. What I don't want to happen is for this to severely
degrade the performance of the application. I think I remember
EditingContext.invalidateAllObjects() causing a pretty poor
performance on high load applications, which this is. Is there some
other way to check whether the keyword is in the system or not before
it's added without incurring such a severe penalty?

I would not suggest any of those solutions.  Are the instances actually changing the descriptor of NewKeywords, just only inserting new ones?  If they are only inserting new ones, there should not be an issue with actual stale data the way you are fetching it.  I suspect your problem may lie elsewhere.


Is there anyway to refault JUST the data in a certain table or of a
certain type of EO and not all the data in an EditingContext.

You can do it object by object, but again, that does not seem to be the problem (or I am misunderstanding your situation).

Chuck

-- 
Coming in 2006 - an introduction to web applications using WebObjects and Xcode     http://www.global-village.net/wointro

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems.    http://www.global-village.net/products/practical_webobjects




_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:

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:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to