Автор оригинала: Vlad Mihalcea.
Одна из моих главных целей для Hibernate-убедиться, что мы предлагаем всевозможные улучшения производительности, чтобы сократить время отклика на транзакции и увеличить пропускную способность. В Hibernate 5.2.10 мы рассмотрели проблему HHH-11542 Jira, которая теперь позволяет вам также задерживать получение соединения с базой данных для локальных транзакций ресурсов.
В этой статье я собираюсь объяснить, как Hibernate получает соединения и почему вы хотите, чтобы он задержал этот процесс как можно дольше.
В режиме гибернации получение соединения с базой данных, а также освобождение соединения зависят от типа текущей транзакции:
- ресурс-локальный: Для транзакций JDBC, которые работают с одним
источником данных,Соединениеприобретается сразу при запуске транзакции и закрывается при завершении транзакции (либо фиксация, либо откат) - JTA: Для транзакций XA, которые охватывают несколько
Источник данныхs,Соединениеприобретается при выполнении первогоОператораи освобождается после каждогоВыполнения оператора. Механизм агрессивного освобождения соединения может быть пропущен, если базовый сервер приложений позволяет нам это сделать.
Наша цель состоит в том, чтобы локальная транзакция ресурсов вела себя как JTA и задерживала получение соединения до тех пор, пока Hibernate не потребуется выполнить первую инструкцию JDBC | для текущей рабочей единицы.
Причину, по которой локальная транзакция ресурсов требует подключения к базе данных с самого начала, можно легко визуализировать на следующей диаграмме:
Hibernate необходимо проверить базовый статус JDBC Подключения автоматической фиксации и отключить его, если для Подключения установлено значение автоматической фиксации. Таким образом, Hibernate может контролировать границы транзакций и следить за тем, чтобы JDBC Оператор /выполнялись в контексте одной и той же транзакции базы данных.
Хотя такое поведение является правильным, поскольку мы не можем знать, был ли установлен флаг автоматической фиксации или нет, мы могли бы подсказать Hibernate пропустить эту проверку, поскольку мы уже знаем, что все JDBC Подключения выполняются в режиме ручной фиксации.
Например, все корпоративные приложения уже используют решение для объединения соединений, которое может отключить режим автоматической фиксации при первом подключении к базе данных.
HikariConfig hikariConfig = super.hikariConfig( dataSource ); hikariConfig.setAutoCommit( false );
По этой причине в Hibernate 5.2.10 мы ввели hibernate.соединение.свойство конфигурации provider_disables_autocommit , которое сообщает Hibernate, что базовое соединение JDBC | уже отключило режим автоматической фиксации.
Чтобы оценить преимущество в производительности при задержке подключения к базе данных, мы собираемся использовать тестовый случай , который эмулирует ресурсоемкий анализ XML-документа, который выполняется в рамках контекста транзакции JPA.
Если мы не задержим получение соединения, продолжительность синтаксического анализа XML будет добавлена ко времени аренды подключения к базе данных. Однако, как только мы переключимся на новый механизм задержки подключения, время аренды подключения значительно сократится, как показано на графике ниже.
Поэтому, если вы используете транзакции с локальными ресурсами (что является вполне нормой при использовании Spring framework), вам определенно следует настроить пул соединений (например, HikariCP ), чтобы отключить автоматическую фиксацию и предоставить свойство конфигурации Hibernate для задержки получения соединения:
Hibernate-это не просто инструмент ORM, а полноценная платформа доступа к данным. Поскольку управление подключением к базе данных очень важно для высокопроизводительного корпоративного приложения, режим гибернации позволяет свести к минимуму время, необходимое для выполнения транзакции с базой данных, что также приводит к повышению пропускной способности транзакций.