Лучшие практики, которые следует соблюдать для вызовов БД без транзакций в Spring MVC и Hibernate
Я разрабатывал приложение с аннотацией @Transactional для класса обслуживания Spring. Для доступа к слою БД у меня есть класс AbstractDao, который при необходимости возвращает текущий сеанс. т.е.
@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessionFactory;
protected Session getSession() {
session = sessionFactory.getCurrentSession();
}
protected Criteria createEntityCriteria() {
return getSession().createCriteria(persistentClass);
}
public List<T> findByCriteria(Criterion criterion) {
Criteria criteria = createEntityCriteria();
criteria.add(criterion);
return criteria.list();
}
Я думаю об удалении транснациональной поддержки, поскольку она мне действительно не нужна, и я хочу повысить производительность вызовов БД, поскольку мне приходится поддерживать большое количество операций вставки БД в секунду.
1) Можно ли использовать не транснациональные операции с БД в Hibernate и Spring?
2) Так как я могу изменить приведенный выше код для поддержки без транзакций? Могу ли я создать приведенный выше код следующим образом?
private Session session;
protected Session getSession() {
if (session == null) {
session = sessionFactory.openSession();
}
return session;
}
Так что createEntityCriteria() может вызвать getSession() get session. Таким образом, мы можем управлять одним сеансом на запрос пользователя (HTTP-запрос MVC весны) с помощью приведенного выше кода.
Если все в порядке, тогда я должен закрыть сеанс в конце пользовательского запроса? Поэтому, если в секунду поступает 300 пользовательских запросов MVC, он открывает 300 вызовов JDBC в БД (так как sessionFactory.openSession() создает новый вызов JDBC).
1 ответ
Создание транзакций не является дорогой операцией, и поэтому перенос метода, который выполняет операцию только для чтения, не сильно повысит производительность при использовании большинства типичных приложений.
Но всякий раз, когда приложение планирует изменить данные по какой-либо конкретной причине, они должны быть заключены в транзакцию, особенно если вы изменяете несколько таблиц, например, изменяете отношение сущностей и т. Д. Это гарантирует, что несколько операторов SQL объединяются вместе и видны только другим сеансам во время фиксации всех изменений, но не раньше. Это очень важно для поддержания целостности базы данных.
Производительность вставки часто в большей степени зависит от других факторов, помимо того, создаете ли вы транзакцию, например, от того, решили ли вы использовать IDENTITY
, AUTO_INCREMENT
, или же SEQUENCE
первичный ключ по сравнению с естественным ключом и / или установлен ли правильный размер пакета JDBC.
Более того, веб-приложение, скорее всего, будет страдать от головной боли, связанной с производительностью, в коде обработки веб-фреймворка, чем от того, будете ли вы беспокоиться о том, используете вы транзакцию или нет:).
Что касается вызовов JDBC, то здесь снова полезен пул соединений.
Он только раздает указанное максимальное количество подключений к приложению, и как только этот предел достигнут, дальнейшие запросы на подключения можно либо попросить подождать несколько секунд в надежде, что соединение станет доступным, либо немедленно вызвать исключение, позволяя приложению обращаться с этим по мере необходимости.