我的进程有一个性能问题。它是在CMT bean (在jboss服务器上)中启动的异步任务。
1次迭代通过Hibernate对我的数据库执行1次更新和3次插入。该过程被划分为每100次迭代的新事务。
在每次update/insert之后在EntityManager上调用Flush。
虽然第一批的启动性能令人满意(大约5-8秒),但随着时间的推移,它会急剧下降。第三十批需要大约30秒才能完成,然后每批增长到超过2分钟。
我尝试将FlushModeType切换为提交,手动清除/关闭entityManagers,清除entityManagers缓存,我查找了内存泄漏,但找不到导致速度变慢的原因。
我测量了很少的代码执行时间,涉及数据库连接的每一段代码都会随着时间的推移而变慢。我知道一个事务会随着处理更多的实体而变慢,但是为什么新的事务也会变慢呢?
最新的流程包含250,000次迭代(1个线程中有2500个事务),并且永远不会结束。
如果需要,我会提供更多信息。任何帮助都将不胜感激。
我试着简化这段代码,只做一次hibernate插入,不做其他操作,但它仍然会随着时间的推移而变慢。这是一个抽象的伪视图,里面发生了什么。
Bean1
@Asynchronous
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void mainTask(){
while(...){
subTask();
}
}
Bean2
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void subTask(){
100.times{
3*Insert
1*Update
}
}发布于 2013-07-22 19:51:45
事实证明这是一个java的问题,我们在不同的配置上测试了我们的应用程序,当我们的jboss在java 1.7 (与1.6相反)上运行时,它工作得很好。每批处理大约在5秒内完成。我们现在反对选择将我们的java升级到1.7,或者更深入地挖掘,找出我们在java 1.6上的设置有什么问题。
发布于 2013-07-19 11:21:07
我确信我的建议可能不准确,或者你已经尝试过了,但我想试一试。正如您提到的DB连接是瓶颈,我将继续讨论这个问题。
读完问题后,我发现事务所用的时间与迭代次数成正比。因此,看起来在第一次迭代中创建的实体将在下一次迭代中发送到hibernate。
例如,在第四次迭代中,在第一次、第二次和第三次迭代中创建的实体也被发送更新或以某种方式发送到hibernate。
这可能是随着迭代的进行而导致性能下降的原因。因为要更新/插入/选择的记录的数量随着每次迭代而增加。
我能想到以下几种可能性--
在第一次迭代中使用的
Hibernate提供了一种打印发送到数据库的实际SQL查询/参数的方法。您可以检查发送到数据库的实际查询。此链接- How to print a query string with parameter values when using Hibernate
发布于 2013-07-19 21:08:34
在使用JPA执行批处理程序的过程中,我们遇到过几次类似的问题。我们能找到的唯一解决方案就是对批处理程序使用jdbc api,这涉及到大量的处理。
https://stackoverflow.com/questions/17727366
复制相似问题