#performance #hibernate #playframework
#Производительность #спящий режим #playframework
Вопрос:
У меня есть две модели: пользовательская и базовая.
Пользовательская модель: http://pastebin.com/WdLzBkHJ
Базовая модель: http://pastebin.com/tQrEUaSu
Сначала я хочу обратить ваше внимание на это обозначение в базовой модели:
@org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)
Это не работает (в SQL Debug показано, что спящий режим генерирует запросы с использованием ненужных столбцов, которые в MySQL настроены как обнуляемые). Скажите мне, пожалуйста, почему? Что я делаю не так?
И основная проблема здесь (метод, при котором пользователь загружает базу, а строка в этой базе вставляется в таблицу MySQL после синтаксического анализа): http://pastebin.com/yG3Mapze
Вставка выполняется ОЧЕНЬ МЕДЛЕННО. У меня есть файл с 70000 строками в строке, и я не могу дождаться, пока спящий режим вставит эту строку в БД. Максимум, я ждал 30 минут, и это был не конец. Если я буду использовать такие необработанные запросы:
DB.execute("INSERT INTO bases (user_id,email,password) VALUES (1,'" email.replaceAll("'", "'") "','" password.replaceAll("'", "'") "')");
вместо
b.save();
После этого вставка 70000 строк в БД завершается через ~ 10-20 секунд.
Итак, я не могу понять, в чем проблема и как ее исправить?
Также вы можете увидеть этот код выше объявления метода:
@NoTransaction
Если я раскомментирую его, я получу это исключение:
@689mbad1k Внутренняя ошибка сервера (500) для запроса POST / checker / uploadnewbase
Ошибка JPA Произошла ошибка JPA (контекст JPA не инициализирован. Диспетчер объектов JPA автоматически запускается, когда один или несколько классов аннотируются с помощью @javax.persistence.Аннотации объектов находятся в приложении.):
воспроизведение.исключения.JPAException: контекст JPA не инициализирован. Диспетчер объектов JPA автоматически запускается, когда один или несколько классов аннотируются с помощью @javax.persistence.Аннотации объектов находятся в приложении. в play.db.jpa.JPA.get(JPA.java: 22) в play.db.jpa.JPA.em(JPA.java: 51) в play.db.jpa.JPQL.em(JPQL.java: 16) в play.db.jpa.JPQL.EM.найти (JPQL.java: 44) в models.User.find(User.java ) у контроллеров.Security.getUser(Security.java: 30) на контроллерах.GlobalController.userStat(GlobalController.java: 21) в play.mvc.ActionInvoker.invoke(ActionInvoker.java: 502) в play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java: 476) в play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java: 471) в play.mvc .ActionInvoker.Обработкаfores(ActionInvoker.java:320) в play.mvc.ActionInvoker.invoke(ActionInvoker.java:140) при вызове.HTTP-запрос (воспроизведение!)
Но в руководстве по воспроизведению мы видим, что: «Если вы хотите вообще запретить Play запускать какие-либо транзакции, вы можете аннотировать метод с помощью @play.db.jpa.NoTransaction .
Чтобы предотвратить транзакции для всех методов, вы можете аннотировать класс контроллера с помощью @play.db.jpa.NoTransaction «.
Итак, у меня есть три проблемы, которые я описал:
- Об исключении в NoTransaction.
- Об использовании dynamicInsert = true.
- Об улучшении производительности для гибернации, например, если я буду использовать необработанные запросы.
Ответ №1:
Проблема заключается в сеансе гибернации, который необходимо очистить. В противном случае у вас возникнут проблемы с памятью и производительностью. Вы можете найти некоторую информацию в http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html . К сожалению, я не знаю, как получить HibernateSession. Возможно, вы можете получить EntityManager и работать с ним. Но мой опыт работы с гибернацией и пакетной обработкой действительно разочаровывает, поэтому я бы рекомендовал использовать ваше raw-решение.
Комментарии:
1. Да, спасибо, я уже читал о batch on jboss.org и результаты меня разочаровали. Вставки выполняются слишком медленно. Поэтому я использую сейчас raw-решение для этого цикла. Но я не могу понять, что делает спящий режим, кроме настройки свойств модели, и почему вставка такая медленная.
2. Кстати, вы не знаете решение для dynamicInsert и исключения после NoTransaction?
3. @purple: я не специалист по спящему режиму, но, насколько я знаю, существует много метаинформации, которая должна обрабатываться в фоновом режиме, которые увеличиваются экспоненциально. О вашем вопросе: я понятия не имею.
4. Вы можете запустить сеанс воспроизведения в режиме гибернации
Session session = (Session) JPA.em().getDelegate();
, а затем использоватьsession.flush`` and
session.clear()`, как описано в документации в ответе. Вы также можете создать новый сеанс исключительно для импорта.