Сохраняет ли данные пружины во время метода @Transactional объекты в
ОЗУ или объекты, которые были очищены, доступны для мусора
коллектор
Объекты будут храниться в ОЗУ (т. Е. В entityManager
) до тех пор, пока не будет очищен фиксация / откат транзакции или entityManager. Это означает, что сущности имеют право на GC только в случае фиксации / отката транзакции или
entityManager.clear()
называется.
Итак, каков наилучший подход для обработки огромного количества данных с
данные весны?
Общая стратегия предотвращения OOM заключается в загрузке и обработке пакета данных за пакетом. В конце каждого пакета вы должны очищать и очищать entityManager
, чтобы entityManager
мог высвобождать свои управляемые объекты для CG. Общий поток кода должен выглядеть примерно так:
@Component
public class BatchProcessor {
//Spring will ensure this entityManager is the same as the one that start transaction due to @Transactional
@PersistenceContext
private EntityManager em;
@Autowired
private FooRepository fooRepository;
@Transactional
public void startProcess(){
processBatch(1,100);
processBatch(101,200);
processBatch(201,300);
//blablabla
}
private void processBatch(int fromFooId , int toFooId){
List<Foo> foos = fooRepository.findFooIdBetween(fromFooId, toFooId);
for(Foo foo :foos){
//process a foo
}
/*****************************
The reason to flush is send the update SQL to DB .
Otherwise ,the update will lost if we clear the entity manager
afterward.
******************************/
em.flush();
em.clear();
}
}
Обратите внимание, что эта практика предназначена только для предотвращения ООМ, но не для достижения высокой производительности. Поэтому, если производительность не является вашей заботой, вы можете смело использовать эту стратегию.