Bugs item #554437, was opened at 2002-05-10 03:51
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=376685&aid=554437&group_id=22866
Category: JBossCMP
Group: v2.4 (stable)
Status: Open
Resolution: None
Priority: 5
Submitted By: Paul Nicklin (paulnicklin)
Assigned to: Nobody/Anonymous (nobody)
>Summary: Finders methods not "concurrency Safe"?
Initial Comment:
Hi all,
We're seeing an occasional problem where two calls to
finder methods made 'simultaneously' from different
instances of a session bean result in each being
returned a different remote object, but referring to
the same data.
This would not ordinarily be a big problem (the
concurrency/ optimistic locking system will prevent
the second update conflicting)
But in our case this entity bean is supporting the
High-Low pattern for giving out unique IDs, so two
Customers with the same key fails! (Won't go into
detail, but basically you have a table with "UniqueID
Name", "Unique ID NextValue" and you use this and
another number to give all your objects a unique ID -
I'd give you a URL but I don't have one- sorry!)
A bit of digging in the entity cache code (Isn't open
source wonderful!) says to me that if the row isn't in
the cache then two threads will run through the code
both saying...
"Is the row in the cache?"
"NO! - I'll go fetch it"
"Here's the row from the database, lets put it in the
cache"
"Here you go client, have a reference to the entity"
now, both call the getNextValue method and get the
next value and update the database - but because they
are not the same instance in they both update the
database to the same next value.
Then my code uses the value to create "customer" rows,
but the second fails because of a constraint violation
(Extract from CMPPersistenceManager.java)
public Object findEntity(Method finderMethod, Object[]
args, EntityEnterpriseContext ctx)
throws Exception {
// For now only optimize fBPK
if (finderMethod.getName().equals("findByPrimaryKey"))
{
Object key = ctx.getCacheKey();
if (key == null)
{
key = ((EntityCache)con.getInstanceCache
()).createCacheKey(args[0]);
}
if (con.getInstanceCache().isActive(key))
{
return key; // Object is active -> it exists -> no
need to call finder
}
}
// The store will find the entity and return the
primaryKey
Object id = store.findEntity(finderMethod, args, ctx);
// We return the cache key
return ((EntityCache) con.getInstanceCache
()).createCacheKey(id);
}
I'd suggest we check after calling the finder that the
object is STILL Not in the cache, reducing the window
of opportunity for duplication... currently the window
of opportunity for this failure includes the database
fetch time, a few hundred ms possibly, doing my change
would reduce this to a few microseconds.
Thanks for your perseverance in reading this far - any
comments? Am I completely up the wrong tree?
Suggestions welcome...
Paul Nicklin
[EMAIL PROTECTED]
----------------------------------------------------------------------
>Comment By: Bill Burke (patriot1burke)
Date: 2002-05-10 10:15
Message:
Logged In: YES
user_id=176497
Sorry to be harsh, but I don't believe you. Are you using
any custom container-configurations? Make sure you have
the correct interceptor chains, especially
EntityLockInterceptor and correct locking-policy
(QueuedPessmisticEJBLock). Also, make sure that your
PrimaryKey class implements hashCode and equals correctly.
#1, There is only one active valid instance of any Entity
bean. A finder call does NOT create an entity bean, nor
does it insert one into the cache. An entity bean instance
is only created when a method is invoked upon it.
#2 Your statements below are incorrect
"Is the row in the cache?"
"NO! - I'll go fetch it"
"Here's the row from the database, lets put it in the
cache"
"Here you go client, have a reference to the entity"
A finder does NOT fetch the row, nor does it put the row in
cache. The sql call for a finder only returns primary
keys. But, are you using "read-ahead"? Behaviour is
different with read-ahead.
My guess is that you've implemented your primary keys
incorrectly.
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=376685&aid=554437&group_id=22866
_______________________________________________________________
Have big pipes? SourceForge.net is looking for download mirrors. We supply
the hardware. You get the recognition. Email Us: [EMAIL PROTECTED]
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development