Мы размещаем сервис (сервлет, выполняющийся на jboss), который получает что-то вроде 5-6 запросов в секунду. Каждому запросу необходимо подключиться к mysql через спящий режим. Большинство наших запросов выбирают, с вставкой/обновлением каждые 5/6-й запрос. Соединение hibernate mysql получает тайм-аут после тайм-аута соединения mysql (8 часов). Даже после того, как запрос на обслуживание нашего сервиса каждый час, соединение mysql иногда случайно отключается через день или около того. Мы хотим, чтобы спящий режим был повторно подключен, если соединение отключено по какой-либо причине и поддерживает количество подключений, к которым мы хотим.Соединение с гибернацией/mysql
Мы пытались C3P0, со следующей конфигурацией:
<property name=c3p0.acquire_increment>1</property>
<property name=c3p0.idle_test_period>3600</property>
<property name=c3p0.max_statements>0</property>
<property name=c3p0.min_size>1</property>
<property name=c3p0.timeout>3605</property>
<property name=hibernate.c3p0.preferredTestQuery>select 1;</property>
Hibernate размер connection_pool был установлен в 1.
Это сделало проблему тайм-аут/отключение уйти. Но мы столкнулись с другой проблемой. Долго ждет. Обычно время подачи запроса для нас составляет 2-3 мс для выбора и 40-50 мс для вставки/обновления. Но после использования вышеуказанной конфигурации C3P0 мы увидели, что каждый запрос, завершающийся после обновления, занимает больше минуты, а иногда и 4-5 минут! Из наших журналов казалось, что случайным образом запрос на выбор зацикливается и сможет завершить только после того, как будет получен и обслужит запрос на обновление.
Проблема выше, если мы удалим конфигурацию C3P0. Может кто-нибудь предположить, что мы можем делать неправильно?
Вот полный спящий режим конфигурации для справки:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://xxx.xxx.xxx</property>
<property name="connection.username">xxx</property>
<property name="connection.password">xxx</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="show_sql">true</property>
<!-- Transaction isolation 2 = READ_COMMITTED -->
<property name="connection.isolation">2</property>
<property name="connection.autocommit">true</property>
<!-- configuration pool via c3p0-->
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">3600</property> <!-- seconds -->
<property name="c3p0.max_size">1</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.timeout">3605</property> <!-- seconds -->
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
</session-factory>
</hibernate-configuration>
hmmm, в настоящее время мы полностью удаляем управление соединением в спящем режиме, то есть мы запрашиваем только hibernate для текущего соединения (getCurrentConnection()), а затем выполняем запрос на нем. Мы никогда не открываем и не закрываем соединение явно в нашем коде. Возможно, нам нужно пересмотреть эту стратегию. – ashweta
Но тогда мы также требуем высокой производительности (<50 мс). Мы не можем позволить себе открывать и закрывать соединение db каждый раз, когда приходит запрос. Итак, infact нам нужно объединить открытые соединения, которые поддерживаются hibernate/JNDI, которые мы можем использовать, не закрывая их сами. – ashweta
@ashweta: Вам нужно прочитать это - http://www.hibernate.org/117.html. Поиск «Hibernate - это утечка JDBC-соединений!» Должен закрыть сеанс. Что касается производительности, то у вас есть пулы. «Закрыть» в этом случае действительно означает «возврат в пул». – duffymo