【发布时间】:2016-12-13 22:51:06
【问题描述】:
我有一个使用 Spring、Hibernate 和 JTA 的应用程序。
我们收到的请求包含超出预期的数据(10000 个元素),一般请求为 10-100 个元素。
在处理这个请求时,我们尝试在 DB 中为每个元素插入一条记录,这是在 for 循环中完成的
伪代码:
processRecords( list){
for (Element element: list){
dao.findBy -- This takes around 100 ms
-- some other checks and logic
dao.add(element); -- This takes around 150 ms
dao.flush();
}
}
这个块需要很多时间来处理记录,然后我得到 *
"javax.persistence.TransactionRequiredException: 没有事务在 进步”
*
我尝试将刷新移出 for 循环,但没有帮助,我尝试研究 hibernate 的批量插入,但这是一个具有大量自定义的大型应用程序,我不认为这是一个选项,因为它会影响整个应用程序,我还尝试查找配置的事务持续时间在哪里,我能找到的唯一地方是 weblogic 上的 JTA,它设置为 480 秒。
任何关于如何解决这种情况的指标将不胜感激。
编辑: 增加 weblogic 中的 JTA Timeout 暂时解决了这个问题,但是我将它设置为一个非常大的值 5000 秒,有没有提高性能,因为我只是插入 8K 记录(我知道批处理是一种选择,但是有是自定义“框架”中的一些限制)
【问题讨论】:
-
你使用 JPA 还是原生 hibernate。请提供持久化数据的代码 sn-p。为了持久化数据,您需要在 JDBC/DB 级别进行事务处理,如果您使用 spring 管理的 hibernate/JPA,您通常通过将 @Transactional 添加到您的 dao 方法来做到这一点。
-
我们在 jms 队列中收到请求,并在从队列中读取消息(入站 jms)时添加了@Transactional,整个事务从那里开始
-
你的数据库是什么?似乎数据更改量对于您的提供商来说太多了,就像它无法将其之前的图像数据保存在它拥有的任何临时存储中,然后事务会自动回滚。打开 Hibernate 调试并查看那里是否发生任何事情也可能会有所帮助。
-
您在配置事务管理器时是否设置了超时属性?
-
根据具体情况,有许多可能的解决方案。批量获取数据应该已经对您的情况有所帮助。在每个元素之后不冲洗也可能有所帮助。也许您可以使用多线程解决方案?