Каковы необходимые настройки C3P0 для гибернации, чтобы избежать тупиковых ситуаций? - PullRequest
46 голосов
/ 24 января 2009

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

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

  • c3p0-0.0.1.2.jar
  • MySQL-разъем-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 персистентность с hibernate описаны параметры конфигурации 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. Каждый из них использует hibernate с файлом конфигурации, почти эквивалентным показанному выше (изменяются только имя пользователя, имя базы данных, пароль и сопоставление ресурсов).

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

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>

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

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?

Ответы [ 6 ]

48 голосов
/ 17 сентября 2010

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

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

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

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

8 голосов
/ 13 августа 2009

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

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

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

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

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

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

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

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

3 голосов
/ 10 января 2014

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

Между тем, во-вторых, сколько раз нужно разорвать соединение.

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

1 голос
/ 30 августа 2017
    <property name="hibernate.c3p0.timeout">300</property>     
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

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

1 голос
/ 18 августа 2009

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

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

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

0 голосов
/ 24 января 2009

Разделяют ли три приложения один и тот же пул соединений, или у каждого есть свой собственный? Я бы порекомендовал последнее.

...