Многие потоки, созданные с использованием C3P0 с Hibernate/Spring

Я делаю проект, объединяющий Hibernate и Spring в веб-приложении Java, используя Tomcat в среде Linux. Из-за проблемы тайм-аута Mysql 8 часов мы хотим использовать C3P0 для управления пулом соединений с нашей базой данных Mysql. Но когда мы его используем, у нас создается множество потоков. Я понял это, потому что при каждом запросе я печатал их все со статусом памяти, который показывает мне увеличение памяти и такие потоки:

  • имя: C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|39c446]-HelperThread-#0 демон: настоящая группа! основная группаParent: система активна: истина прервана: ложь
  • имя: C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|17ec0e8]-AdminTaskTimer демон: истинная группа! основная группаParent: система активна: истина прервана: ложь

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

Вот мой Hibernate.cfg.xml:

    <property name="connection.provider_class">
            org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="hibernate.c3p0.acquire_increment">1</property> 
    <property name="hibernate.c3p0.idle_test_period">5</property>
    <property name="hibernate.c3p0.max_size">100</property> 
    <property name="hibernate.c3p0.max_statements">100</property> 
    <property name="hibernate.c3p0.min_size">10</property> 
    <property name="hibernate.c3p0.timeout">5</property>

    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myBase</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.default_schema">myProject</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
    <property name="show_sql">false</property>

    <property name="cache.provider_class">
      org.hibernate.cache.NoCacheProvider
    </property>         

Я также попытался добавить файл свойств C3P0, но, кроме уменьшения номера вспомогательного потока, он не удаляет неиспользуемый поток:

    c3p0.maxStatements=5    

c3p0.maxIdleTime=10

c3p0.numHelperThreads=1

c3p0.testConnectionOnCheckout=true
c3p0.preferredTestQuery=SELECT 1

c3p0.initialPoolSize=1
c3p0.minPoolSize=1
c3p0.maxPoolSize=10

c3p0.acquireIncrement=1
c3p0.idleConnectionTestPeriod=1

Кто-нибудь знает, почему это происходит и как решить эту проблему?

Большое спасибо.


person user954156    schedule 12.12.2012    source источник


Ответы (3)


если вы видите умножение вспомогательных и таймерных потоков c3p0, вы каким-то образом создаете множество источников данных c3p0, когда хотите, чтобы был только один. иногда это происходит, если вы перезагружаете свое приложение, но забываете закрыть() свой старый источник данных c3p0 при повторном использовании.

фактически это выглядит так, как будто вы «сливаете» DataSources. вам нужно выяснить, почему/где это происходит. для некоторых подсказок проверьте свои журналы на наличие сообщений инициализации c3p0 DataSource на уровне INFO. Найдите, например, строку «Инициализация пула c3p0».

удачи!

person Steve Waldman    schedule 12.12.2012

Хорошо, я нашел комбинацию свойств для решения моей проблемы, имея в виду, что мне не нужно много соединений одновременно:

  • c3p0.maxStatements=5
  • c3p0.maxIdleTime=10
  • c3p0.numHelperThreads=3
  • c3p0.testConnectionOnCheckout=истина
  • c3p0.preferredTestQuery=ВЫБЕРИТЕ 1
  • c3p0.initialPoolSize=1
  • c3p0.minPoolSize=1
  • c3p0.maxPoolSize=1 c3p0.acquireIncrement=1
  • c3p0.idleConnectionTestPeriod=1
  • c3p0.maxAdministrativeTaskTime=1

Спасибо всем

person user954156    schedule 13.12.2012
comment
Добавление idleConnectionTestPeriod=1 слишком агрессивно. Я бы не рекомендовал это. - person Atif Imran; 20.09.2013

Я ожидаю, что он создаст количество потоков, пропорциональное c3p0.minPoolSize и c3p0.maxPoolSize, а ваш максимум равен 10.

http://www.mchange.com/projects/c3p0/#other_ds_configuration "< strong>numHelperThreads и maxAdministrativeTaskTime помогают настроить поведение пулов потоков DataSource. По умолчанию каждый DataSource имеет только три связанных вспомогательных потока. Если кажется, что производительность падает при большой нагрузке, или если вы наблюдайте с помощью JMX или прямой проверки PooledDataSource, что количество «ожидающих задач» обычно больше нуля, попробуйте увеличить numHelperThreads. maxAdministrativeTaskTime может быть полезен для пользователей, сталкивающихся с задачами, которые зависают на неопределенный срок, и сообщениями «APPARENT DEADLOCK» (см. Приложение A). для большего.) "

numHelperThreads определяет, сколько потоков используется для каждого источника данных, поэтому на самом деле у вас будет 10 потоков с numHelperThreads=1.

Единственный способ убедиться, что C3P0 использует только один поток, — это установить c3p0.minPoolSize и c3p0.maxPoolSize в 1, но это противоречит цели пула соединений.

person SkyWalker    schedule 12.12.2012
comment
Если я установлю c3p0.numHelperThreads=0, мой запрос никогда не завершится, и по умолчанию значение равно 3. - person user954156; 12.12.2012
comment
Вы можете попробовать, но я ожидаю, что что-то не сработает, я ожидаю, что эти потоки будут отслеживать состояние соединений для вас и, возможно, делать больше. - person SkyWalker; 12.12.2012
comment
Я пробовал с c3p0.numHelperThreads=3 и c3p0.maxAdministrativeTaskTime=10, и ничего не изменилось. - person user954156; 12.12.2012
comment
вы только что увеличили количество потоков. Помните, что он запускает соединения и потоки в зависимости от нагрузки. Если вы просто инициализируете его без какой-либо рабочей нагрузки (создание множества подключений и т. д.), он может их не запустить. - person SkyWalker; 12.12.2012
comment
Привет, здесь немного ошибка. numHelperThreads — это количество потоков, созданных для каждого источника данных, а не для каждого соединения. numHelperThreads=1 обычно не очень хорошая идея. - person Steve Waldman; 12.12.2012