Connections checking in c3p0 pool

前端 未结 3 1935
误落风尘
误落风尘 2021-02-10 07:41

I\'m developing with Java SE application using Hibernate 4 and c3p0 for communication with MariaDB database. It\'s long running application, waiting for signals from outside, so

相关标签:
3条回答
  • 2021-02-10 08:25

    Ok, i managed to fix all problems. Here is soultion.

    First of all, as Steve Waldman suggested, c3p0 wasn't actually initialized, but in Hibernate 4.3 hibernate.connection.provider_class parameter should be: org.hibernate.c3p0.internal.C3P0ConnectionProvider. In documentation you can read:

    A connection provider that uses a C3P0 connection pool. Hibernate will use this by default if the hibernate.c3p0.* properties are set.

    But in my opinion it's good to put this parameter by yourself, and it's needed if you are using c3p0 config file, not hibernate.c3p0.* properties.


    Second problem was obtaining session by calling SessionFactory.openSession() at the begining of the thread and later using always the same session object. I suppose after database connection was broken and there was new one recreated in pool, using old session caused using old, broken connection. So possible solutions were obtaining new session by SessionFactory.openSession() after catching connection error or using SessionFactory.getCurrentSession() at the begining of every communication. I've decided to use the second option (in this case my application waits for external signal, sometimes for hours, so I'm obtaining current session after each signal).


    My final configuration:

    hibernate.cfg.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
        <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?zeroDateTimeBehavior=convertToNull&amp;autoReconnect=true</property>
        <property name="hibernate.connection.username">user</property>
        <property name="hibernate.connection.password">pass</property>
        <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
    
        <property name="hibernate.current_session_context_class">thread</property>
    
        <property name="show_sql">true</property>
        <property name="use_sql_comments">true</property>
    
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <property name="hibernate.cache.use_query_cache">true</property>
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        </session-factory>
    </hibernate-configuration>
    

    c3p0-config.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <default-config>
        <property name="initialPoolSize">5</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">10</property>
        <property name="checkoutTimeout">3000</property>
        <property name="maxStatementsPerConnection">30</property>
    
        <property name="preferredTestQuery">SELECT 1 FROM DUAL</property>
        <property name="testConnectionOnCheckin">true</property>
        <property name="testConnectionOnCheckout">false</property>
        <property name="idleConnectionTestPeriod">300</property> <!-- 5 minutes -->
        </default-config>
    </c3p0-config>
    

    With this c3p0 configuration:

    • Every 5 minutes of not performing any queries on connection it will be tested, so it will never be invalidated by DB (in standard configuration MySQL invalidates connection after 8 hours of inactivity),
    • If DB will be restarted or connection(s) will be manually killed we have two options: a) after max 5 minutes connections will be reestablished, b) if application tries to perform query before automatic connection reestablishing HibernateException will be thrown, then connection will be reestablished and next query will succeed.

    Optionally testConnectionOnCheckout could be set to true to prevent exceptions, but it will cause performance troubles (see documentation).

    0 讨论(0)
  • 2021-02-10 08:26

    Try setting testConnectionOnCheckout to true in your c3p0-config.

    0 讨论(0)
  • 2021-02-10 08:30

    are you sure c3p0 is actually initialized, and that it has the config you expect it to have?

    in your logs, at INFO level, you should see a dump of your c3p0 DataSource's config upon pool initialization. verify that it is there, and that it is the configuration you expect.

    if it is not there, please consider adding the following line to your hibernate.cfg.xml:

    <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" /> 
    
    0 讨论(0)
提交回复
热议问题