Toplink/java 持久性之谜时间接收器
我有一个 servlet 通过本地接口调用会话 bean。 会话方法的最后一个语句与 servlet 中该方法调用之后的语句之间有 3 秒的暂停。
我已经确定了会话 bean 中的哪个语句导致方法返回时出现额外的延迟,但我只是不知道为什么会有这样的暂停以及发生了什么:
会话 bean 方法:
public void getXMLByDatesPlCtry(PrintWriter out, Date dateStart, Date dateEnd, int plId, String ctry) throws ParserConfigurationException {
Query findCtry = em.createNamedQuery("Ctry.findByCtry");
findCtry.setParameter("ctry", ctry);
Ctry country = (Ctry) findCtry.getSingleResult();
findByDatesPlFcIds = em.createNamedQuery("SortTypeInv.findByDatesPlCtry");
findByDatesPlFcIds.setParameter("dateStart", dateStart);
findByDatesPlFcIds.setParameter("dateEnd", dateEnd);
findByDatesPlFcIds.setParameter("plId", plId);
findByDatesPlFcIds.setParameter("ctry", country);
inventoryList = findByDatesPlFcIds.getResultList(); // statement causing pain
logger.warning("about to return");
}
The servlet 调用会话 bean:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
[...]
sortTypeInvFacade.getXMLByDatesPlCtry(out, lastSunday.getTime(), yesterday.getTime(), pl_id, request.getParameter("ctry"));
Logger.getLogger(InventoryServlet.class.getName()).warning("just received");
} catch (ParserConfigurationException ex) {
Logger.getLogger(InventoryServlet.class.getName()).log(Level.SEVERE, null, ex);
} finally {
out.close();
}
}
因此 3 秒的暂停发生在会话 bean 中的“即将返回”日志消息和 servlet 中的“刚刚收到”日志消息之间。如果在某个阶段调用了有罪的语句(将数据收集到集合中),那么会出现长时间的暂停。 真正令人惊讶的是,浪费的时间不是花在构建集合上,而是花在方法返回上。 在这种情况下,该方法不会返回任何内容。
无论该集合是会话类的私有变量还是局部变量,都不会改变任何内容。 使会话 bean 有状态或无状态也是如此。
怎么了? 如何避免长时间的停顿呢?
I have a servlet calling a session bean via a local interface. There is a 3 second pause between the last statement of the session method and the statement following that method call in the servlet.
I have identified what statement in the session bean causes the extra delay upon method return, but I just have no idea why there is such a pause and what is happening:
The session bean method:
public void getXMLByDatesPlCtry(PrintWriter out, Date dateStart, Date dateEnd, int plId, String ctry) throws ParserConfigurationException {
Query findCtry = em.createNamedQuery("Ctry.findByCtry");
findCtry.setParameter("ctry", ctry);
Ctry country = (Ctry) findCtry.getSingleResult();
findByDatesPlFcIds = em.createNamedQuery("SortTypeInv.findByDatesPlCtry");
findByDatesPlFcIds.setParameter("dateStart", dateStart);
findByDatesPlFcIds.setParameter("dateEnd", dateEnd);
findByDatesPlFcIds.setParameter("plId", plId);
findByDatesPlFcIds.setParameter("ctry", country);
inventoryList = findByDatesPlFcIds.getResultList(); // statement causing pain
logger.warning("about to return");
}
The servlet calling the session bean:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
[...]
sortTypeInvFacade.getXMLByDatesPlCtry(out, lastSunday.getTime(), yesterday.getTime(), pl_id, request.getParameter("ctry"));
Logger.getLogger(InventoryServlet.class.getName()).warning("just received");
} catch (ParserConfigurationException ex) {
Logger.getLogger(InventoryServlet.class.getName()).log(Level.SEVERE, null, ex);
} finally {
out.close();
}
}
So the 3 seconds pause happens between the "about to return" log message in the session bean and the "just received" log message in the servlet. It only does that long pause if at some stage the incriminating statement (gathering data into a collection) is called. What's really surprising is that the wasted time is not spent building the collection, but rather upon method return. And in this instance nothing is returned by the method.
Whether the collection is a private variable of the session class or a local variable doesn't change anything. Same goes with making the session bean stateful or stateless.
What is happening? How can that long pause be avoided?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果不知道完整的代码,很难回答。
我猜想这要么与退出会话 bean 时提交的事务有关,要么与退出会话 bean 后执行的某些拦截器有关。
另外,我会尝试注释掉 .getResultSet() 调用以查看它是否有任何效果。
It's hard to answer without knowing your full code.
I would guess it is either related to transaction being committed upon exiting from session bean, or maybe some interceptors that are executing after the exit from session bean.
Also I would try to comment out the .getResultSet() call to see if it has any effect.
我的猜测是你触发了一个巨大的垃圾收集。 尝试启用允许您跟踪垃圾收集的标志。
对于 Sun JVM,这似乎是 -verbose:gc
My guess is that you have a huge garbage collection triggered. Try enabling the flag that allows you to follow garbage collections.
For the Sun JVM this appears to be -verbose:gc