Java Hibernate连接泄漏

Java Hibernate连接泄漏,java,hibernate,struts2,database-connection,struts2-s2hibernate,Java,Hibernate,Struts2,Database Connection,Struts2 S2hibernate,使用Hibernate和Struts2,整个流程如下所示: hibernate.cfg.xmlas: <hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property> <property name="connection.url">jdbc:or

使用Hibernate和Struts2,整个流程如下所示:

hibernate.cfg.xml
as:

<hibernate-configuration>

    <session-factory>
    <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
    <property name="connection.url">jdbc:oracle:thin:@xx.xx.xxx.xx:1521:TEST</property>
    <property name="connection.username">xxxx</property>
    <property name="connection.password">xxxxyyy</property>
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

   <mapping class="test.models.administration.Menus" />

   <mapping resource="Dual.hbm.xml" />
 </session-factory>

 </hibernate-configuration>
然后在我的DAO类中将扩展到上面的DAO,如:

       public class UserRoleDAO extends AbstractSimpleGenericDao<UserRole, UserRoleId> {

          public List L() {
    try {
        String queryString = "from UserRole";
        Query queryObject = hSession.createQuery(queryString);
        return queryObject.list();
    } catch (RuntimeException re) {
        throw re;
    }
      }
如果我通过重复单击指定的菜单链接来调用这个
abc
Action类,那么它会导致连接泄漏,被视为使用jProfiler可以看到的打开的连接,并且永远不会关闭。 同时,它的连接也在泄漏

使用jProfiler对所有打开的泄漏连接进行堆栈跟踪

org.hibernate.transaction.JDBCTransaction.begin()

com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInter
ceptor.injectHibernateTransactionByAnnotation(java.lang.Object, org.hibernate.Session, boolean)

com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInter
ceptor.injectHibernateTransactionByAnnotation(java.lang.Object, org.hibernate.Session, boolean)

com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInter
ceptor.intercept(com.opensymphony.xwork2.ActionInvocation)

java.lang.Thread.run()
URL: /project/action-name
为什么Hibernate正在泄漏这些连接?


这就像,Hibernate将连接保持在会话中并重用相同的连接,因此,如果同时发出并发请求,如果会话连接被占用,它将泄漏连接。这只是我的假设。我不知道。

在hibernate配置中隐式使用了
DriverManager配置提供程序
。默认情况下使用此提供程序,除非您使用属性
connection.provider\u class
对其进行了配置

该提供程序还实现了一个非常基本的连接池

它的意思是“基本连接池”。如果运行应用程序,可以在日志中看到

[DriverManagerConnectionProvider] Using Hibernate built-in connection pool (not for production use!)
[DriverManagerConnectionProvider] Hibernate connection pool size: 20
您还可以通过hibernate配置属性
connection.pool\u size
设置此值。但它并没有将您限制为最大打开连接数。当池为空时,可以根据需要打开任意多个连接。提供程序将在
closeConnection
上返回到池的连接时保持它们打开,除非当前池大小未超过属性
connection.pool\u size
中的值。一旦当前池大小不为空,就无法打开任何新连接,因为连接提供程序将从池返回连接

正如您现在看到的,很难说hibernate在默认情况下使用此连接提供程序可能会泄漏连接,我只是说这是不可能的。但是,它不受打开的连接数的限制

要确保连接受到限制,请使用其他连接提供程序。例如
您可以使用
C3P0ConnectionProvider
并设置属性
hibernate.c3p0.max_size
来限制打开的连接。

在hibernate配置中隐式使用
DriverManager配置提供程序
。默认情况下使用此提供程序,除非您使用属性
connection.provider\u class
对其进行了配置

该提供程序还实现了一个非常基本的连接池

它的意思是“基本连接池”。如果运行应用程序,可以在日志中看到

[DriverManagerConnectionProvider] Using Hibernate built-in connection pool (not for production use!)
[DriverManagerConnectionProvider] Hibernate connection pool size: 20
您还可以通过hibernate配置属性
connection.pool\u size
设置此值。但它并没有将您限制为最大打开连接数。当池为空时,可以根据需要打开任意多个连接。提供程序将在
closeConnection
上返回到池的连接时保持它们打开,除非当前池大小未超过属性
connection.pool\u size
中的值。一旦当前池大小不为空,就无法打开任何新连接,因为连接提供程序将从池返回连接

正如您现在看到的,很难说hibernate在默认情况下使用此连接提供程序可能会泄漏连接,我只是说这是不可能的。但是,它不受打开的连接数的限制

要确保连接受到限制,请使用其他连接提供程序。例如

您可以使用
C3P0ConnectionProvider
并设置属性
hibernate.c3p0.max_size
来限制打开的连接。

如何管理会话?@romac除了如上所述创建DAO之外,我没有做任何管理会话的事情。。。我使用的是Tomcat服务器您使用的是什么版本和插件。您的struts配置是什么?@RomanC使用Struts2、myeclipse、Tomcat 6.x您如何管理会话?@RomanC除了如上所述创建DAO之外,我没有做任何事来管理会话。。。我使用的是Tomcat Server什么版本和什么插件?你的Struts配置是什么?@使用struts2、MyEclipse、Tomcat 6Xi的Roomc只是检查,因为我还没有定义连接。PooLyStand属性,所以默认情况下需要连接20个连接池,即连接增长到20,我想到泄漏,然后再坚持下去。现在我已经定义了connection.pool\u size属性=1。连接仍在增长,但立即恢复为1。这完全可以,但定义pool_size=1有任何缺点。或者更确切地说,当连接不会返回小于定义的限制时,使用池大小>1有什么好处?感谢您提供的解决方案,并且您提到使用C3P0ConnectionProvider hibernate.c3p0.max_size来限制打开的连接。限制打开的连接的数量,是否意味着新请求将不再被服务?现在,如果connection.pool_size property=1,则连接数将超过1,但同时连接数会回落到1。所以在这里,连接会增加,但很快也会释放。除非您通过数据库限制连接,否则使用C3P0ConnectionProvider比此?新请求有任何优势。真的不知道它们是如何回退的,如果你关闭了连接,它不会关闭,而是返回到池中。c3p0可以更好地管理连接,即连接的生命周期。打开连接需要花费大量的时间,使用c3p0,这一次的费用将比使用默认连接管理器的费用低。IMHO.我只是检查了一下,因为我没有定义connection.pool_size属性,所以默认情况下需要20个连接池,即连接增长到20个,我认为会泄漏,然后会继续,现在我定义了connection.pool_size属性=1。连接仍在增长,但立即恢复为1。这是完全正确的
[DriverManagerConnectionProvider] Using Hibernate built-in connection pool (not for production use!)
[DriverManagerConnectionProvider] Hibernate connection pool size: 20