Я пытаюсь улучшить производительность моего транзакционного метода asynk.
В этой задаче мне нужно прочитать почти 7500 записей из таблицы, обработать ее и вставить/обновить соответствующую строку в другой таблице.
Я использую весенние данные jpa с спящим режимом.
Чтобы получить ScrollableResults
, я внедряю EntityManager
в свой сервис.
Вот как я получаю свой объект ScrollableResult
:
Session session = (Session) em.unwrap(Session.class);
ScrollableResults res = session.createQuery("from SourceTable s")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
while (res.next()){
.... // em.flush() called every 40 cycles
}
Цикл по результату занимает около 60 секунд.
И здесь узкое место. Если внутри моего цикла я выполняю простой запрос:
query = em.createQuery("from DestTable d where d.item.id = :id", DestTable.class);
while (res.next()){
query.setParameter("id", myId).getSingleResult();
}
Время выполнения становится в 10 раз медленнее... и занимает около 600 секунд.
Я пытался изменить параметр моего Session
или моего EntityManager
: session.setFlushMode(FlushModeType.COMMIT);
em.setFlushMode(FlushModeType.COMMIT);
Это увеличивает производительность и удаляет метод ручного сброса (), работа выполняется за 40 секунд !!!
Итак, мои вопросы:
- В чем разница вызова
setFlushMode
наsession
или наenityManager
? - Почему
setFlushMode(FlushModeType.COMMIT);
увеличивается производительность таким образом, и я не могу иметь такую же производительность, только вручную очищая entityManager?