Bugs item #554437, was opened at 2002-05-10 03:51
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=554437&group_id=22866

>Category: JAWS (inactive)
Group: v2.4 (stable)
Status: Open
>Resolution: Wont Fix
>Priority: 1
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: Dain Sundstrom (dsundstrom)
Date: 2002-09-12 12:23

Message:
Logged In: YES 
user_id=251431

JAWS is no longer actively maintained.  We will accept
patches, and will fix bugs can be fixed on a contract basis.
 Furthermore, JAWS will be removed in JBoss 4.0.

----------------------------------------------------------------------

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: 
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=554437&group_id=22866


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to