【问题标题】:Spring JPA: keeping the persistence context smallSpring JPA:保持持久性上下文小
【发布时间】:2021-07-19 18:56:47
【问题描述】:

如何在 Spring JPA 环境中保持较小的持久化上下文?

为什么:我知道通过保持较小的持久性上下文,会显着提升性能!

主要问题领域是:

@Transactional
void MethodA() { 
   WHILE retrieving next object of 51M (via a stateless session connection) DO
      get some further (readonly) data
      IF condition holds THEN
        assessment = retrieve assession object (= record from database)
        change assessment data
        save the assessment to the database
}

通过在这个问题域中的实验,我知道每 250 次迭代清理一次持久化上下文时,性能会好很多。

当我将这些行添加到代码中时,每 250 次迭代:

@PersistenceContext
private EntityManager em;

WHILE ... 
   ...
   IF counter++ % 250 == 0 THEN
       em.flush()
       em.clear() 
}

然后我收到诸如“无法可靠地执行刷新操作”之类的错误。

我尝试将主要事务设置为只读,并将评估保存部分设置为“事务需要新”,然后出现“在分离实体上操作”之类的错误。很奇怪,因为我从不重新访问一个开放的实体。

那么,我怎样才能使持久性上下文保持较小? 已经尝试了 10 种方法。非常感谢您的帮助。

【问题讨论】:

  • 如果你想在那里使用flush和clear,我建议你删除@Transactional注释。该注释告诉 Spring(以及随后的 Hibernate 和数据库)它必须将所有内容保存在内存中,直到提交,在您的情况下,这是大量数据。
  • 感谢您的反应!我可以在没有任何@Transactional 的情况下从数据中读取这么多数据吗?

标签: spring hibernate jpa hibernate-jpa


【解决方案1】:

我建议您将所有条件逻辑移到查询中,这样您甚至不必加载那么多行/对象。或者更好的是,编写一个更新查询,在单个事务中完成所有这些操作,这样您就不需要在应用程序和数据库之间传输任何数据。

我认为无状态会话不需要刷新,因为它不保持状态,即它会在每次操作后刷新并清除持久性上下文,但除此之外,我还认为这可能不是你想要的真的很想要,因为这可能会导致重新获取数据。

如果您不希望持久化上下文被填满,则使用 DTO 获取数据并执行更新语句以刷新更改。

【讨论】:

    猜你喜欢
    • 2013-10-31
    • 2023-03-18
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 2015-11-22
    相关资源
    最近更新 更多