跳到导航
dev2dev.bea.com.cn
首页 资源中心 dev2dev学堂 在线技术论坛 专家Blog User Group CodeShare
dev2dev 首页 > 资源中心 > 专家Blog > 专家Blog文章
EJB实体缓存和事务

时间:2005-04-14
作者:Dmitri Maximovich
浏览次数:
本文关键字:cachesizetransaction缓存容量事务
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章
EJB实体缓存和事务

大家都知道EJB容器支持实体Bean缓存。通常在特定于供应商的部署描述符中为每个Bean配置缓存容量。在WebLogic中是weblogic-ejb-jar.xml文件的max-beans-in-cache元素。如果不指定该元素的值,就使用默认值1000。

可能是因为缓存容量在说明文档中被完全描述为一个性能最优化参数,许多开发人员没有意识到,许多其他的因素也会影响到缓存容量的选择。

一个可能不那么明显的事实就是,当事务使用实体bean时,bean实际上被加载到实体缓存中,而且在事务的整个持续时间内,bean都“固定”在缓存中,即使代码并没有修改实体bean,而只是在读取它的值。

举例来说,设想一下会话bean或MDB Bean中的代码正在执行实体bean Person的finder方法,然后迭代所返回的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
        ...
    }
    ...

如果findSomething()方法返回的对象超出了在max-beans-in-cache中指定的值,在Iterator迭代到第N+1个对象(当前的实体缓存容量是N),应用程序就会收到令人讨厌的(而且很可能是出人意料的)weblogic.ejb20.cache.CacheFullException异常。

这看起来没什么大不了的,有人还会说反正finder也不会返回太大的collection等等。但是不要忘了,首先,WebLogic默认的实体缓存是多版本的(multiversioned),这意味着如果多个事务请求同一个实体bean,缓存中会创建多个版本(每个事务一个版本),这将大大降低每个对象的缓存容量。其次,容器中同时运行多个事务是很平常的。设想一下如果上面的代码被max-beans-in-free-pool参数值(默认值也是1000)很大的会话bean或MDB bean调用,而且同时来了50个客户机请求。这样每个事务就只可使用实体缓存中1000/50 = 20个槽(slot),如果finder返回了多于20个的对象,那么就有一些事务不能被满足了。

这是在设计带有大量实体bean的操作时需要记住的。更糟糕的情况是,开发人员通常使用相当小的数据库,这使问题在开发时完全看不出来,而在部署代码时使用的是生产环境的数据库,问题就出现了。作为应对的措施,我建议在开发时不要使用默认的内存容量设置,而将其设置为非常低的值(10-100),这样就可以在开发的早期阶段发现并解决与缓存相关的问题。

 

评论

  • CacheFullException的bug,我以前曾经对此发表过评论,它只出现在特定的环境中(会话bean和CMP bean的事务属性的特定组合)。

BEA已经发布了CR 209987,它可以修补这个bug,并且它也会包含在WLS 8.1 SP5中。

发表人:maximdim,2005年5月9日, 01:32 PM

  • max-beans-in-free-pool参数控制WebLogic中的匿名 bean实例的池的最大容量。该参数不会对性能造成太大影响,因为在如今的JVM中,对象的实例化操作开销并不大(除非您的对象需要大量开销才能实例化)。更何况,从空闲池中获取实体bean实例的操作通常都会成功,即使池是空的。如果池是空的,将会创建新的bean实例并返回,所以空闲池用完也不会出现异常。我建议,如果您的实体bean的创建开销不太大的话,最好不要修改max-beans-in-free-pool参数。

至于您的例子:50个同时的请求,每个返回5000个对象——至少对于默认的多版本缓存策略,缓存空间足可以容纳50x5,000=250,000个bean。但是要注意您的内存消耗。我还想问问,如何设计会使一次调用需要返回5,000个对象?

发表人:maximdim,2005年4月18日,08:17 AM

  • 嗨,Dmitri,对于如何设置EJB实体缓存和事务的max-beans-in-cache和max-beans-in-free-pool参数,我有一点糊涂了。如果我的应用程序必须处理50个同时的客户机请求,而且每个请求要返回5000个对象,我是否就应该把max-beans-in-cache设置为5000,而max-beans-in-free-pool设置为250000?谢谢。

发表人:taifook,2005年4月17日,09:41 PM

发表人: maximdim,2005年4月15日,10:39 AM

原文出处:http://dev2dev.bea.com/blog/maximdim/archive/2005/04/ejb_entity_cach.html

dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分

   
相关技术