EJB programming & troubleshooting: Database bottlenecks - Entity Bean solution?
- Posted by: John King
- Posted on: April 16 2002 06:19 EDT
I've inherited a database whose redesign will take ages (don't even ask!). In the meantime, I need to rewrite parts of an app (on weblogic 6.1) to take some load off the db. Entity beans come to mind, because many of the users of the system are querying the same records, and the container should be able to cache some of these. However, some things have me stumped...
1. Given that my primary concern is db performance (I can easily extra throw machines onto the appserver cluster), is there a practical limit, within the confines of the JVM's heap size, to the max pool size of a particular entity bean? How about 100? 1000? 10000?
2. Does Weblogic (or any other app servers) use the Least-Recently-Used algorithm to decide what entity beans to dump from the pool?
Thanks for any help,
- Database bottlenecks - Entity Bean solution? by Neeraj Nargund on April 16 2002 11:31 EDT
- Database bottlenecks - Entity Bean solution? by Steven Wisener on April 16 2002 13:48 EDT
- Database bottlenecks - Entity Bean solution? by John King on April 16 2002 15:36 EDT
- Database bottlenecks - Entity Bean solution? by Pranab Ghosh on April 16 2002 16:10 EDT
1.I think the the max pool size is vendor specific.
2.U can set the property in the descriptor file.
The following example shows the structure of the cache-type element.
NRU=Not recently used.
LRU=Least recently Used.
Sorry, I suppose I should clarify my quesion a bit.
I'm wondering if setting the max pool size in the descriptor to figures such as 100 or 1000 or 10000 would have nasty runtime implications, even if the RAM was there to support it.
I'd strongly suggest against entity beans for trying to improve performance. While it sounds like a good idea in theory, I just don't think it works in practice. I'm not sure what other application servers can do; we're using WebLogic 5.1 with BMP.
Of course, the idea is that with entity beans, you can look up the data once and have it hang around in memory without hitting the database. With WebLogic you can do this only if you set the db-is-shared flag to false. That means nothing else is touching the database except your application; this makes sense, it couldn't guarantee the entity beans were up to date otherwise.
Now get ready for the killer: you can't set db-is-shared to false in a WLS cluster AT ALL, even using CMP. I don't believe this restriction was lifted in WLS 6; I'm not sure about WLS 7. That means ejbLoad for every bean at the beginning of every transaction = performance nightmare.
As far as I can tell, entity beans are good for one thing and one thing only, and that's portability between databases. The bottom line is if you're already locked into a database solution that you're not going to extricate yourself from, don't use entity beans. If you think you'll need to port to another database and can deal with the restrictions, go with entity beans. If you're trying to improve performance, entity beans will rarely help (at least for WLS, only if you have nothing else touching the database and you only have a single WLS instance).
I'd personally like to know if any other application servers deal with entity bean caching better than WLS...
Hi Stephen -
Thanks for your reply. Yes, you're right about the "db-is-shared" setting. However, with more recent versions of Weblogic, there is the concept of a "Read-Only" entity bean. An entity bean is made Read-Only with a setting in a descriptor. Anyway, these particular EJBs can work in a clustered environment. They have a setting (stored in a descriptor) indicating how long the EJB should go between refreshing itself from the db.
As far as I can tell, entity beans are good for one thing and one thing only, and that's portability between databases.
I disagree. I use EB primarily to leverage the caching benifits of read only or read mostly data that is accessed frequently. I use the commit option A, which prevents unnecessary calls to ejbLoad()at the beginning of transactions.
I disagree. I use EB primarily to leverage the caching
> benifits of read only or read mostly data that is
> accessed frequently.
So that means either:
1. You mark the entity beans as read only.
2. You have only one WebLogic instance.
3. You aren't using WebLogic, but another application server that does cache management on a cluster wide basis.
I'm not sure about most applications, but ours has almost no read only data. If you're able to mark a substantial amount of entities as read only, that would probably work.
> I use the commit option A, which prevents unnecessary
> calls to ejbLoad()at the beginning of transactions.
I don't know how "you" are using commit option A. Are you saying you set some flag in your application server that tells it how to manage transactions? If so, you're betting that other application servers will also have that functionality; otherwise, either your portability is shot or your performance is.
Aside from the religious reference -- i.e. "the only good thing ejb is good for..." I agree with Steven. If you're just trying to increase performance in an application that isn't component based, EJB is going to hurt you more than it helps you.
The short version of my advice would be to build a cache yourself. It isn't very difficult and you'll save alot of time and effort. The long answer -- with plenty of opinion -- follows...
EJB assumes an instance driven persistence methodology and JDBC assumes a type-driven methodology. If you are writing component based software you will find that EJB provides alot of the services that you will need. If not then it just raises the footprint of your app and introduces alot of new problems that you have to get around.
EJB's caching is pretty primitive. It helps you out mostly when you're referring to the same bean over and over within the same transaction or if you want to prefetch objects into the cache. But these are really only things that you do when you're treating beans as instances in a component architecture.
The EJB answer to Steven's problem of always reading at the beginning of a transaction is to use a read-mostly pattern. You just have two beans, a reader that is read-only and an updater that is read-write. If you're smart about the way you code them you can do this with a minimum of extra code. Of course, why even bother if you aren't writing component-based software?
Just using EJB doesn't get you much database portability. Yes, the container provider will take care of some of the type mapping for you, but that breaks quite often. Real database portability comes from taking constraints and stored procedures out of your database and placing them into an entity bean. You'll take a performance hit because you have to have the related rows in memory to check the constraints, but you'll gain a great deal of portability.
The fact that container providers aren't comming up with better caching mechanisms shows that they're asleep at the switch. It's time for a better mousetrap.