【发布时间】:2016-06-23 17:15:58
【问题描述】:
我在使用 Hibernate 时遇到了性能问题。
Hibernate : 3.2.6.ga
JDK : jdk1.6.0_45
我有一个被注释为@Transactionnal 的函数,它链接到一个EntityManager。
这个函数是循环调用的,所以我有:
for (Item i : itemList)
{
saveIt(i);
}
如果我启动它 5/10/20 次就可以了,处理时间似乎没有增加。 但是如果我启动它 300/400 次,“保存”的时间就会越来越慢...... 我监控了java内存,并没有看到什么奇怪的东西。
所以我找到了一些关于 Flush/Clean 魔法解决方案的文章。 我试过了,hourra,它有效。
for (Item i : itemList)
{
saveit(i);
cleanMySession();
}
但对我来说这很奇怪,因为我认为 @Transactionnal 注释管理了所有这些东西,特别是当我在这个循环之外不做任何与 Hibernate 相关的事情时......也许我有点迷茫...... .
最后一个问题:这种解决方法安全吗?
注意:实际上saveIt函数在数据操作方面是相当庞大的,所以处理时间很重要,不能增加。
编辑 - 附加信息:
我在 cleanSession 函数的调试模式下停止了:
public void cleanSession() {
Session session = (Session) em.getDelegate();
session.flush();
session.clear();
}
这是堆栈:
MyServiceImpl.cleanSession() line: 177
GeneratedMethodAccessor216.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 319
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 196
$Proxy40.cleanSession() line: not available
MyAction.doSave() line: 814
StrutsStack...
所以是的,我看到了一些代理,但对我来说,这个代理来自 Spring Injection 而不是来自 Hibernate。
编辑 N°2:
是的,我使用 OpenSessionInView 过滤器
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
</filter>
【问题讨论】:
-
包含 for 循环的方法的名称是什么?你也可以在堆栈中报告它吗(如果你过滤了它)?
-
这是 MyAction 类中的“doSave”。它是 Struts 控制器类。
-
好的,我猜for循环在
MyAction.doSave()方法中。除了 $Proxy40 之外,您在堆栈中没有其他 $Proxy (在堆栈上方,在打印的堆栈跟踪下方)?你使用 openSessionInViewFilter 吗? -
使用过滤器进行新编辑。
-
我已更新我的答案以添加有关 openSessionInViewFilter 为何触发您看到的行为的信息
标签: java performance hibernate session