我完全失去了,我正在使用hibernate和mysql运行一个批处理作业,几个小时之后我得到一个例外,说我正在使用许多连接。我已经阅读了有关SO的所有文章,但似乎没有与我有关。我正在使用Tapestry-hibernate,配置非常简单http://tapestry.apache.org/using-tapestry-with-hibernate.html。不管我在哪里创建一个新的SessionFactory,一旦应用程序启动,我只是将hibernate Session注入我的类。
这是我当前与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();
}
}
}
}
}
}
答案 0 :(得分:1)
tapestry-hibernate提供的hibernate会话是PerThread作用域。 PerThread作用域服务通过PerthreadManager.cleanupThread()进行清理。 Tapestry自动清理由ParallelExecutor管理的请求线程和线程。如果您正在管理自己的线程,则必须显式调用PerthreadManager.cleanupThread()。
答案 1 :(得分:-1)
考虑到Session对象不是线程安全的,可能是你定义被注入的会话对象的方式有问题。
实现者不应该是线程安全的。相反,每个线程/事务应该从SessionFactory获取自己的实例。