Too many connections Hibernate and mysql

2019-05-28 13:35发布

问题:

I'm at a complete loss, I'm running a batch job using both hibernate and mysql and after a few hours I get an exception saying I'm using to many connections. I've read all the articles on SO, but none seem to relate to me. I'm using Tapestry-hibernate with a very simple configuration, http://tapestry.apache.org/using-tapestry-with-hibernate.html. No where's am I creating a new SessionFactory, once the application starts up, I just inject the hibernate Session into my class.

This is my current connection view with mysql.

My batch job is threaded and everytime a new thread fires off, the threads_connected seems to increment.

my cfg.xml file.

<hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.datasource">jdbc/company</property>
    <property name="hbm2ddl.auto">validate</property>
    <property name="hibernate.show_sql">false</property>

    <property name="hibernate.search.default.directory_provider">filesystem</property>
    <property name="hibernate.search.default.indexBase">/users/george/Documents/indexes </property>

    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.use_query_cache">false</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
</session-factory>

Sample of basic session usage in class - "please note below code is not production code, just used to illustrate session usage.

private final Session session;

public LineReaderParserImpl(Session session) {
    this.session = session;
}

public void parse() {
    exec.submit(new Runnable() {
        public void run() {
          for (int i = 0; i < 10000; i++) {
            Object object = session.createCriteria()...

            session.save(object);
            session.getTransaction().commit();

            if (currentRow % 250 == 0 || currentRow == totalRows) {
                try {
                    session.getTransaction().commit();
                } catch (RuntimeException ex) {
                    try {
                        session.getTransaction().rollback();
                    } catch (RuntimeException rbe) {
                        throw ex;
                    } finally {
                        session.clear();
                        session.beginTransaction();
                    }
                }
            }  
         }              
    }
}

回答1:

The hibernate session provided by tapestry-hibernate is PerThread scoped. PerThread scoped services are cleaned up via PerthreadManager.cleanupThread(). Tapestry automatically cleans up request threads and threads managed by ParallelExecutor. If you are managing your own thread, you must call PerthreadManager.cleanupThread() explicitly.



回答2:

Considering that Session Object is not thread-Safe maybe there's something wrong with the way you are defining the session object which is getting injected.

It is not intended that implementors be threadsafe. Instead each thread/transaction should obtain its own instance from a SessionFactory.