使用无状态会话 bean 后 MDB 是否应该调用remove()?
我们已有多年历史的 WebLogic J2EE 应用程序有一个消息驱动的 Bean,它使用无状态会话 Bean。 MDB onMessage 方法获取无状态会话 bean 的 home 接口,并调用 home 接口的 create()
方法来获取实际的无状态会话 bean 本身。
该代码不会尝试缓存会话 bean,只是直接使用它:
public void onMessage(Message message)
{
...
MySessionBeanLocal ejbLocal = MySessionBeanLocalHome.create();
ejbLocal.myMethod();
MDB 中没有相应的 remove()
调用。
我的问题是:在这种情况下不调用 remove()
是不是很糟糕?
我相当确定需要为有状态会话 bean 调用 remove()
,但我不太清楚 remove()< /code> 调用对于无状态是必要的。
我们最近取得了显着的性能改进,但突然开始在负载下用完有状态会话 bean,出现以下异常:
java.lang.RuntimeException: An invocation of EJB MyMessageDrivenBean(Application:
MyApplication, EJBComponent: MyApplication.jar) timed out while waiting to get an instance from the free pool.
at weblogic.ejb20.pool.StatelessSessionPool.waitForBean(StatelessSessionPool.java:229)
at weblogic.ejb20.pool.StatelessSessionPool.getBean(StatelessSessionPool.java:100)
at weblogic.ejb20.manager.StatelessManager.preInvoke(StatelessManager.java:140)
at weblogic.ejb20.internal.BaseEJBLocalObject.preInvoke(BaseEJBLocalObject.java:228)
at weblogic.ejb20.internal.StatelessEJBLocalObject.preInvoke(StatelessEJBLocalObject.java:53)
at MyMessageDrivenBean_x56omo_ELOImpl.processMessage(MyMessageDrivenBean_x56omo_ELOImpl.java:28)
at MyMessageDrivenBean.onMessage(TBMessageListener.java:94)
at weblogic.ejb20.internal.MDListener.execute(MDListener.java:370)
at weblogic.ejb20.internal.MDListener.onMessage(MDListener.java:262)
at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:2678)
我们的 MDB 池设置为:
<message-driven-descriptor>
<pool>
<max-beans-in-free-pool>20</max-beans-in-free-pool>
<initial-beans-in-free-pool>5</initial-beans-in-free-pool>
我们的无状态会话 bean 池设置为:
<stateless-session-descriptor>
<pool>
<max-beans-in-free-pool>50</max-beans-in-free-pool>
<initial-beans-in-free-pool>5</initial-beans-in-free-pool>
我的问题是,调用 的 MDB 是无状态会话 bean 上的 create()
还负责调用无状态会话 bean 的 remove()
吗? (该应用程序似乎已经运行多年而没有调用 remove()
,但我想知道吞吐量的提高是否暴露了一个旧的错误。)
Our years-old WebLogic J2EE application has a message-driven bean which makes use of a stateless session bean. The MDB onMessage method gets the home interface of the stateless session bean and calls the home interface's create()
method to get the actual stateless session bean itself.
The code does not attempt to cache the session bean, just uses it directly:
public void onMessage(Message message)
{
...
MySessionBeanLocal ejbLocal = MySessionBeanLocalHome.create();
ejbLocal.myMethod();
There is no corresponding remove()
call in the MDB.
My question is: is it bad not to be calling remove()
in this case?
I'm fairly sure that one is required to call remove()
for a stateful session bean, but it's less clear to me if the remove()
call is necessary for stateless.
We recently made significant performance improvements but suddenly began to run out of stateful session beans under load with this exception:
java.lang.RuntimeException: An invocation of EJB MyMessageDrivenBean(Application:
MyApplication, EJBComponent: MyApplication.jar) timed out while waiting to get an instance from the free pool.
at weblogic.ejb20.pool.StatelessSessionPool.waitForBean(StatelessSessionPool.java:229)
at weblogic.ejb20.pool.StatelessSessionPool.getBean(StatelessSessionPool.java:100)
at weblogic.ejb20.manager.StatelessManager.preInvoke(StatelessManager.java:140)
at weblogic.ejb20.internal.BaseEJBLocalObject.preInvoke(BaseEJBLocalObject.java:228)
at weblogic.ejb20.internal.StatelessEJBLocalObject.preInvoke(StatelessEJBLocalObject.java:53)
at MyMessageDrivenBean_x56omo_ELOImpl.processMessage(MyMessageDrivenBean_x56omo_ELOImpl.java:28)
at MyMessageDrivenBean.onMessage(TBMessageListener.java:94)
at weblogic.ejb20.internal.MDListener.execute(MDListener.java:370)
at weblogic.ejb20.internal.MDListener.onMessage(MDListener.java:262)
at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:2678)
Our MDB pool is set to:
<message-driven-descriptor>
<pool>
<max-beans-in-free-pool>20</max-beans-in-free-pool>
<initial-beans-in-free-pool>5</initial-beans-in-free-pool>
Our stateless session bean pool is set to:
<stateless-session-descriptor>
<pool>
<max-beans-in-free-pool>50</max-beans-in-free-pool>
<initial-beans-in-free-pool>5</initial-beans-in-free-pool>
My question is, is the MDB that calls create()
on the stateless session bean also responsible for calling the remove()
for the stateless session bean as well? (The application seems to have run for years without calling remove()
, but I'm wondering if improved throughput has exposed an old bug.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在远程接口对象被垃圾处理后,
remove()
方法无论如何都会被调用。我认为任何 EJB 应用程序都不应强制显式调用 remove() 方法,如果发生这种情况,可能是因为池太小了。 当然,您可以调用always using 进行微调,但这应该是一个例外,而不是规则。
The
remove()
method would be called anyway after the remote interface object is garbaged.I think no EJB application should obligate explicitly calling the remove() methods, if that happens, it's probably because the pool is too small. Of course you call always using for fine-tuning, but this should be an exception, not the rule.