2

我完全不知所措,我正在使用hibernate和mysql运行批处理作业,几个小时后我收到一个异常,说我正在使用许多连接。我已经阅读了所有关于 SO 的文章,但似乎没有一篇与我有关。我正在使用具有非常简单配置的 Tapestry-hibernate,http ://tapestry.apache.org/using-tapestry-with-hibernate.html 。不,我在哪里创建一个新的 SessionFactory,一旦应用程序启动,我只需将休眠会话注入我的类。

这是我当前与 mysql 的连接视图。在此处输入图像描述

我的批处理作业是线程化的,每次启动新线程时,threads_connected 似乎都会增加。

我的 cfg.xml 文件。

<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>

课堂中基本会话使用示例-“请注意以下代码不是生产代码,仅用于说明会话使用。

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();
                    }
                }
            }  
         }              
    }
}
4

2 回答 2

1

Tapestry-hibernate 提供的休眠会话是 PerThread 范围的。PerThread 范围内的服务通过 PerthreadManager.cleanupThread() 进行清理。Tapestry 自动清理请求线程和由 ParallelExecutor 管理的线程。如果您正在管理自己的线程,则必须显式调用 PerthreadManager.cleanupThread()。

于 2013-11-01T08:38:24.210 回答
-1

考虑到 Session 对象不是线程安全的,您定义正在注入的会话对象的方式可能有问题。

实现者并不是线程安全的。相反,每个线程/事务都应该从 SessionFactory 获得自己的实例。

于 2013-11-01T04:34:11.017 回答