Question

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. enter image description here

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();
                    }
                }
            }  
         }              
    }
}
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top