我正在使用GWT和Hibernate,c3p0和MySQL来制作一个有限的用户(每天最多50个用户)的web应用程序。在测试过程中,我发现Hibernate会打开一个与每个会话的连接,但不会关闭它,这与使用close()方法无关。
我当前的配置如下:
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=
hibernate.connection.username=
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.current_session_context_class=thread
hibernate.c3p0.min_size=1
hibernate.c3p0.max_size=1
hibernate.c3p0.timeout=10
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=10
hibernate.c3p0.unreturned_connection_timeout=1
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider每次与应用程序建立新连接时,都会创建一个新的池。例如,如果我将池大小设置为3,则到应用程序的2个连接将导致6个连接,直到应用程序关闭。
预期的行为是在每个事务之后简单地关闭或重用连接。我如何才能做到这一点?
发布于 2010-09-22 22:07:11
在测试期间,我发现Hibernate会打开与每个会话的连接,但不会关闭它,而不管使用的是close()方法
在使用连接池时,调用Connection#close()不会物理上关闭连接,而是将其返回到池中以供将来重用。换句话说,连接保持打开,这就是使用池的全部意义。
我调用下面的代码: AnnotationConfiguration().buildSessionFactory().getCurrentSession();:
这就是问题所在。您在一次又一次地创建SessionFactory (每个创建自己的池),而您应该在应用程序的生命周期中只创建一次。如果您没有使用任何特定的框架,这通常是在某个实用程序类(著名的HibernateUtil类)中完成的。
官方的Hibernate Tutorial有一个这样的类的非常基本的例子。或者看看this one,它更丰富一些。
发布于 2010-09-22 18:42:05
连接池的概念就是这样。你有一个打开的连接池,当你需要做一个事务时,你已经打开了一个连接。这样,您可以节省大量打开和关闭连接的时间。但是,当您不使用这些连接时,您需要付出代价来保持连接的打开状态。
您有更多关于c3p0 configuration的信息
更新很明显,OP在每个会话中调用一次buildSessionFactory。这必须在应用程序的每个生命周期中调用一次。
下面的实用程序类构建Hibernate的sessionFactory,并将session类提供给任何需要它的人。这是DAO类的cumberstone。
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}发布于 2010-09-22 20:47:52
如果你想在每次交易后关闭连接,那么使用连接池不是一个好的想法。这正是连接池想要避免的……你应该关掉C3PO。Hibernate将自己处理连接(在每个事务中作为简单的JDBC连接打开和关闭)
https://stackoverflow.com/questions/3768263
复制相似问题