0

我的流程存在性能问题。这是一个在 CMT bean 中启动的异步任务(在 jboss 服务器上)。

1 次迭代通过 Hibernate 对我的数据库执行 1 次更新和 3 次插入。该过程每 100 次迭代分为新事务。

每次更新/插入后都会在 EntityManager 上调用 Flush。

虽然第一批的开始表现令人满意(大约 5-8 秒),但随着时间的推移,它会急剧下降。第 30 批大约需要 30 秒才能完成,后来每批增长到 2 分钟以上。

我尝试将 FlushModeType 切换为 COMMIT,手动清除/关闭 entityManagers,清除 entityManagers 缓存,查找内存泄漏,但找不到导致速度变慢的原因。

我测量了一点点代码执行时间,每个涉及数据库连接的代码都会随着时间的推移而变慢。我知道交易会随着处理更多实体而变慢,但为什么新交易也会变慢?

最新的过程由 250 000 次迭代(1 个线程中的 2500 个事务)组成,并且需要永远结束。

如果需要,我会提供更多信息。任何帮助,将不胜感激。

我尝试简化此代码只是为了执行 1 次休眠插入而没有其他操作,但它仍然会随着时间的推移而变慢。这是对内部情况的抽象伪视图。

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
        }
}
4

3 回答 3

0

原来这是一个java问题,我们在不同的配置上测试了我们的应用程序,当我们的jboss在java 1.7上运行时它工作正常(与1.6相反)。每批在大约 5 秒内完成。我们现在反对选择将我们的 java 升级到 1.7 或深入挖掘并找出我们在 java 1.6 上的设置有什么问题。

于 2013-07-22T11:51:45.477 回答
0

在使用 JPA 执行批处理程序期间,我们曾多次遇到类似的问题。我们能找到的唯一解决方案是将 jdbc api 用于涉及大量处理的批处理程序。

于 2013-07-19T13:08:33.733 回答
0

我确信我的建议可能不准确,或者您已经尝试过,但我想试一试。正如您提到的那样,数据库连接是瓶颈,我会继续。

阅读问题后,我发现事务花费的时间与迭代次数成正比。所以看起来在第一次迭代中创建的实体在下一次迭代中被发送到休眠状态。

例如,在第 4 次迭代中,在第 1 次、第 2 次和第 3 次迭代中创建的实体也被发送以进行更新或以某种方式发送到休眠状态。

这可能是迭代进行时性能下降的原因。随着每次迭代要更新/插入/选择的记录数量增加。

我可以想到以下可能性-

  1. 第一次迭代中使用的休眠会话一直使用到结束。因此,在第一次迭代中创建的实体也会在以后的迭代中更新。我读到您尝试关闭实体管理器等。但是,请检查会话结束的位置。您可以在每个事务中创建一个新会话,也可以在每个事务之后删除会话中创建的实体。

  2. 为每次迭代过滤记录的列表正在发送已处理的记录。这意味着列表应该在第三次迭代中发送从 300 到 399 的记录,但是从 0 到 399 的记录被发送到事务。

  3. 如果您使用 HQL,请尝试使用命名查询。上次我使用 Hibernate 时(大约 8 个月前),我注意到当使用 HQL 时,hibernate 加载的对象数量远远超过命名查询。

Hibernate 提供了一种打印发送到 DB 的实际 SQL 查询/参数的方法。您可以检查发送到数据库的实际查询。链接 - How to print a query string with parameter values when using Hibernate

于 2013-07-19T03:21:06.903 回答