Spring JPA:保持持久性上下文小
Spring JPA: keeping the persistence context small
如何在 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()
}
然后我收到类似“无法可靠地执行刷新操作”的错误。
我尝试将主事务和评估保存部分设置为只读 'Transaction-requires-new',然后出现 'operating on a detached entity' 之类的错误。很奇怪,因为我从来没有重访过一个开放的实体。
那么,我怎样才能使持久性上下文变小呢?
已经尝试了 10 种方法。非常感谢帮助。
我建议您将所有条件逻辑移动到您的查询中,这样您甚至不必加载那么多 rows/objects。或者更好的是,编写一个更新查询,在单个事务中执行所有这些操作,这样您根本不需要在应用程序和数据库之间传输任何数据。
我认为无状态会话不需要刷新,因为它不保持状态,即它在每次操作后刷新和清除持久性上下文,但除此之外,我还认为这可能不是您真正想要的,因为这可能会导致重新获取数据。
如果您不希望持久性上下文填满,请使用 DTO 获取数据并执行更新语句以刷新更改。
如何在 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()
}
然后我收到类似“无法可靠地执行刷新操作”的错误。
我尝试将主事务和评估保存部分设置为只读 'Transaction-requires-new',然后出现 'operating on a detached entity' 之类的错误。很奇怪,因为我从来没有重访过一个开放的实体。
那么,我怎样才能使持久性上下文变小呢? 已经尝试了 10 种方法。非常感谢帮助。
我建议您将所有条件逻辑移动到您的查询中,这样您甚至不必加载那么多 rows/objects。或者更好的是,编写一个更新查询,在单个事务中执行所有这些操作,这样您根本不需要在应用程序和数据库之间传输任何数据。
我认为无状态会话不需要刷新,因为它不保持状态,即它在每次操作后刷新和清除持久性上下文,但除此之外,我还认为这可能不是您真正想要的,因为这可能会导致重新获取数据。
如果您不希望持久性上下文填满,请使用 DTO 获取数据并执行更新语句以刷新更改。