Какие требуются настройки C3P0 для гибернации, чтобы избежать взаимоблокировок

Я использую Hibernate вместе с MySQL 5.1.30.

У меня есть следующие библиотеки:

  • c3p0-0.0.1.2.jar
  • mysql-connector-java-5.0.3-bin.jar
  • hibernate3.jar

Я использую hibernate.cfg.xml для конфигурации:

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property> 

        <property name="connection.url">jdbc:mysql://localhost/fooDatatbase</property>
    <property name="connection.username">foo</property>
    <property name="connection.password">foo123</property>

        <!-- Use the C3P0 connection pool provider -->
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <mapping resource="databaselayer/mail/Mail.hbm.xml"/>
        <mapping resource="databaselayer/courses/Course.hbm.xml"/>
        <mapping resource="databaselayer/price/Price.hbm.xml"/>        
        <mapping resource="databaselayer/contact/Contact.hbm.xml"/>
        <mapping resource="databaselayer/artists/Musician.hbm.xml"/>
        <mapping resource="databaselayer/concerts/Concert.hbm.xml"/>     
        <mapping resource="databaselayer/welcome/Welcome.hbm.xml"/>
        <mapping resource="databaselayer/information/Information.hbm.xml"/>                             
    </session-factory>
</hibernate-configuration>

В книге Сохранение JAVA с гибернацией объясняются параметры конфигурации c3p0:

  • hibernate.c3p0.min_size. Это минимальное количество подключений JDBC, которое C3P0 поддерживает всегда готовым.
  • hibernate.c3p0.max_size Это максимальное количество подключений в пуле. Если это число исчерпано, во время выполнения создается исключение.
  • hibernate.c3p0.timeout (вы указываете период тайм-аута (в данном случае 300 секунд), по истечении которого неактивное соединение удаляется из пула).
  • hibernate.c3p0.max_statements Максимальное количество операторов, которые будут кэшироваться. Кэширование подготовленных операторов необходимо для лучшей производительности Hibernate.
  • hibernate.c3p0.idle_test_periods Это время простоя в секундах перед автоматической проверкой соединения.

Я использую Java 1.5.0_09 и tomcat 6.0. У меня есть три приложения, развернутых в Tomcat. Каждый из них использует спящий режим с файлом конфигурации, почти эквивалентным показанному выше (меняются только имя пользователя, имя базы данных, пароль и ресурсы сопоставления).

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

Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@2437d -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1dc5cb7 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@9cd2ef -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4af355 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1275fcb -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:35 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run

Кажется, это ошибка, которую уже получили несколько человек. Я изменил свои настройки, пытаясь следовать описанному здесь обходному пути http://forum.hibernate.org/viewtopic.php?p=2386237 на:

<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.min_size">0</property>
<property name="hibernate.c3p0.max_size">48</property>
<property name="hibernate.c3p0.timeout">0</property>
<property name="hibernate.c3p0.max_statements">0</property>

С новыми настройками я не получаю тупиков, но получаю:

WARNING: SQL Error: 0, SQLState: 08S01
Jan 24, 2009 5:53:37 AM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.io.EOFException

STACKTRACE:

java.io.EOFException
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)

Кто-нибудь знает, что я делаю не так и как правильно настроить c3p0?


person Sergio del Amo    schedule 24.01.2009    source источник
comment
Я предполагаю, что каждое приложение получает свой собственный пул приложений, потому что у меня есть три файла hibernate.cfg.xml, подобные тем, которые размещены в папке WEB-INF / classes приложений.   -  person Sergio del Amo    schedule 25.01.2009
comment
Понятно, что вам нужно снять его стопорный болт.   -  person Paul Nathan    schedule 25.01.2009
comment
У всех ли у них одно и то же имя JNDI? Если да, они просят Tomcat искать соединение из того же пула. Для каждого проекта требуется отдельное имя JNDI, чтобы у них был отдельный пул. Вы должны увидеть 3 пула JNDI в инструменте администрирования Tomcat. Если я прав, ты сейчас увидишь только один.   -  person duffymo    schedule 26.01.2009
comment
Вы имеете в виду инструмент менеджера Tomcat? или другой инструмент?   -  person Sergio del Amo    schedule 26.01.2009
comment
не могли бы вы объяснить, как вы решили проблему? или хотя бы выберите лучший ответ спасибо.   -  person Jack    schedule 15.05.2014


Ответы (6)


На самом деле это, вероятно, слишком поздно, но проблема довольно проста: hibernate.c3p0.idle_test_periods не должно быть выше, чем hibernate.c3p0.timeout, иначе соединения, закрытые базой данных, не будут должным образом обнаружены.

Более того, предупреждения об обнаружении взаимоблокировки выглядят так, как будто какая-то часть вашего кода неправильно возвращает подключения к пулу (например, session.close ())

Исключения MysqlIO возникают, когда ваше приложение простаивает, а MySQL закрывает соединение на сервере. Теперь, если C3P0 не проверяет, действительно ли соединение действительно подключено, вы получаете исключения EOFExceptions.

Надеюсь, это может быть полезно.

person Thomas Weber    schedule 17.09.2010

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

Первый пункт - это ссылка https://www.hibernate.org/214.html, поскольку похоже, вы сделали это и пошли дальше. Вот несколько советов;

  • numHelperThreads: вспомогательные потоки, которые не удерживают конкурирующие блокировки. Распространение этих операций на несколько потоков
  • maxStatements: размер глобального кэша PreparedStatement c3p0.
  • maxStatementsPerConnection: количество PreparedStatements, которые c3p0 будет кэшировать для одного соединения в пуле.
  • maxAdministrativeTaskTime: параметр, который принудительно вызывает метод прерывания () потока задачи, если задача превышает установленный предел времени

Первые три параметра могут улучшить или снизить производительность в зависимости от установленного значения, где четвертый параметр может прервать поток после установленного лимита и дать изменение для запуска другому потоку.

Приблизительные значения

  • numHelperThreads = 6
  • maxStatements = 100
  • maxStatementsPerConnection = 12
  • maxAdministrativeTaskTime = необходимо достаточно времени, чтобы тяжелый запрос мог выполняться в производственной среде

maxStatements и maxStatementsPerConnection следует тестировать в течение нескольких месяцев, так как из-за этих параметров мало точек публикации в мертвой блокировке.

Также будет полезно обратиться к этим ссылкам;

person Community    schedule 13.08.2009

hibernate.c3p0.idle_test_periods должно быть меньше h * ibernate.c3p0.timeout *, потому что первое - это всего лишь значение времени, при котором спящий режим проверяет наличие свободных подключений и пытается чтобы закрыть это.

Между тем, второй - это время, в течение которого соединение должно быть разорвано.

Если idle_test_periods больше, чем параметр тайм-аута, чем спящий режим, ищите все, что имеет значение NULL или не существует в системе. По крайней мере, я так понял.

person user2935659    schedule 10.01.2014

Это довольно старая версия Connector / J. Чтобы убедиться, что вы не боретесь с известной и исправленной ошибкой, я бы начал с получения самой новой (5.0.8):

http://dev.mysql.com/downloads/connector/j/5.0.html

Это EOFException от MysqlIO немного подозрительно. При нормальном использовании или использовании без ошибок вы никогда не должны получать ошибок от этого уровня.

person Trenton    schedule 18.08.2009

    <property name="hibernate.c3p0.timeout">300</property>     
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

Значение idle_test_period должно быть меньше значения тайм-аута.

person jprism    schedule 29.08.2017

У трех приложений один и тот же пул подключений или у каждого свой собственный? Я бы рекомендовал последнее.

person duffymo    schedule 24.01.2009
comment
Я предполагаю, что каждое приложение получает свой собственный пул приложений, потому что у меня есть три файла hibernate.cfg.xml, подобные тем, которые размещены в папке WEB-INF / classes приложений. - person Sergio del Amo; 25.01.2009