Arch2Arch Tab BEA.com
Syndicate this blog (XML)

EJB Entity cache and transactions

Bookmark Blog Post

del.icio.us del.icio.us
Digg Digg
DZone DZone
Furl Furl
Reddit Reddit

Dmitri Maximovich's Blog | April 14, 2005  11:50 AM | Comments (5)


Everybody know that EJB Container supports Entity Beans caching. Usually cache size is configured per Bean in vendor-specific deployment descriptor. In WebLogic it's weblogic-ejb-jar.xml file, max-beans-in-cache element. If value of this element is not specified, default of 1000 is used.

Probably because it's described in documentation purely as performance-optimization parameter not all developers realize that there are some other implications which could dictate selection of proper cache size.

One of the dependencies, which sometime not immediately obvious, is that when your transaction uses Entity beans they're actually loaded and 'pinned' in Entity cache for the duration of transaction even if your code is not modifying Entity beans but just reading values from it.

For example, imagine that code in Session or MDB Bean is executing finder method on Entity bean Person and then iterates over returned Collection:

    ...
    Collection persons = personLocalHome.findSomething();
    
    for (Iterator iter = persons.iterator(); iter.hasNext();) {
        PersonLocal person = (PersonLocal)iter.next();
        Long id = person.getId();
        // do something: log, send email, etc
        ...
    }
    ...

If findSomething() method returns more objects than value specified in max-beans-in-cache your application will get unpleasant (and most likely unexpected) weblogic.ejb20.cache.CacheFullException exception when Iterator gets to the N+1 object (where N is the current Entity cache size).

This could seems like not such big of a deal and one could argue that finders should not return very large collections anyway, etc. but don't forget that first of all by default WebLogic Entity cache is multiversioned, which means if multiple transactions requests the same Entity bean multiple versions (one for each transaction) is created in the cache which could effectively lower cache capacity in terms of unique objects and second is that it's normal to have multiple simultaneous transactions running in container at the same time. Imagine if code above getting called from Session or MDB bean which deployed with high value in max-beans-in-free-pool parameter (which by default is 1000 as well) and there are say 50 simultaneous client requests coming in. This will leave every transaction with just 1000/50 = 20 slots in Entity cache to use and if finder returns more than 20 objects, well some of transactions are going to fail.

This is just something to keep in mind while designing operations with large number of Entity beans. Situation also worsened the fact that developers often works with pretty small database sizes where this problem could not introduce itself at all until code is deployed against production-size database. As a safeguard measure I would suggest in development not to use default settings for cache size but set it at artificially low value (10-100) so cache-related problems could be discovered and fixed at early stages of development.


Comments

Comments are listed in date ascending order (oldest first) | Post Comment

  • Hi Dmitri, I am a little confused about settings for max-beans-in-cache and max-beans-in-free-pool in regards to EJB entity cache and transactions. If my application has to handle 50 simultaneous client requests and each request will return 5000 objects. Does that mean I need to set my max-beans-in-cache to 5000 and max-beans-in-free-pool to 250000? Thanks, Vincent

    Posted by: taifook on April 17, 2005 at 9:41 PM

  • Vincent,

    max-beans-in-free-pool parameter is controlling maximum size for pool of anonymous bean instances in WebLogic. This parameter doesn’t' affect performance much because in modern JVMs instantiation of objects are not really expensive operation (unless your objects are expensive to instantiate ;-). Moreover, an attempt to obtain an entity bean instance from the free pool will always succeed, even if the pool is empty. If the pool is empty, a new bean instance will be created and returned so there could not be any exceptions if your free pool exhausted. I would recommend not bother with changing max-beans-in-free-pool parameter, again if your entity beans not doing anything expensive on creation.

    As for your example of 50 simultaneous requests each returning 5000 objects - at least you should have enough space in cache to hold 50x5,000=250,000 beans with default multi-versioning cache policy. Watch your memory consumption though and I would question design where you need to return 5,000 objects in one call ;-)

    Posted by: maximdim on April 18, 2005 at 8:17 AM

  • It seems that there is a bug with clearing the entiry cache after CacheFullException is thrown, at least in WLS 8.1. See this thread in dev2dev news group.

    Posted by: maximdim on April 18, 2005 at 11:25 AM

  • Bug with CacheFullException, that I previously mentioned is only manifest itfelf under certain circumstances (particular combination of transactional attributes on Session and CMP beans).

    BEA has CR 209987 available which fixes that bug and it is going to be included in WLS 8.1 SP5 as well.

    Posted by: maximdim on May 9, 2005 at 1:32 PM



Only logged in users may post comments. Login Here.

Powered by
Movable Type 3.31