Лучшие практики, которые следует соблюдать для вызовов БД без транзакций в 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, то здесь снова полезен пул соединений.

Он только раздает указанное максимальное количество подключений к приложению, и как только этот предел достигнут, дальнейшие запросы на подключения можно либо попросить подождать несколько секунд в надежде, что соединение станет доступным, либо немедленно вызвать исключение, позволяя приложению обращаться с этим по мере необходимости.

Другие вопросы по тегам