Mysql 我的春天&x2B;hibernate应用程序不关闭jdbc连接

Mysql 我的春天&x2B;hibernate应用程序不关闭jdbc连接,mysql,spring,hibernate,tomcat,jdbc,Mysql,Spring,Hibernate,Tomcat,Jdbc,我在生产中有一个Spring+Hibernate+Tomcat+MySql应用程序,我遇到了一个问题。我认为应用程序没有关闭它的jdbc连接,当它达到极限(目前为200)时,应用程序停止响应,我必须重新启动tomcat。我需要在某处关闭此连接吗?这是我的数据源: <?xml version="1.0" encoding="UTF-8"?> <Context path="/" override="true" reloadable="false" swallowOutput="fa

我在生产中有一个Spring+Hibernate+Tomcat+MySql应用程序,我遇到了一个问题。我认为应用程序没有关闭它的jdbc连接,当它达到极限(目前为200)时,应用程序停止响应,我必须重新启动tomcat。我需要在某处关闭此连接吗?这是我的数据源:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/" override="true" reloadable="false" swallowOutput="false">
    <!-- jdbcInterceptors, removeAbandoned, removeAbandonedTimeout van juntos, ver http://www.tomcatexpert.com/blog/2012/01/24/using-tomcat-7-jdbc-\
    connection-pool-production, y https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html -->
    <!-- removeAbandonedTimeout es en segundos -->

    <Resource name="jdbc/catWDB" auth="Container" type="javax.sql.DataSource"
              driverClassName="com.mysql.jdbc.Driver"
              factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
              url="@URL@"
              username="@USERNAME@"
              password="@PASSWORD@"

              maxActive="200"
              maxIdle="50"
              minIdle="10"
              suspectTimeout="60"
              timeBetweenEvictionRunsMillis="30000"
              minEvictableIdleTimeMillis="60000"

              validationQuery="select 1"
              validationInterval="30000"
              testOnBorrow="true"

              removeAbandoned="true"
              removeAbandonedTimeout="60"
              abandonWhenPercentageFull="10"
              maxWait="10000"

              jdbcInterceptors="ResetAbandonedTimer;StatementFinalizer"


            />

</Context>
类别域对象映射如下:

@Entity
@Table(name = "category")
public class Category implements Comparable, Serializable {
this.getSession().clear();
所以我的猜测是,考虑到米特里达斯的评论,我正在手动使用hibernate会话,我需要用如下方式关闭它们:

@Entity
@Table(name = "category")
public class Category implements Comparable, Serializable {
this.getSession().clear();
或者我可以实现@PersistenceContext。 有谁能告诉我这个实现,这样我就可以评估哪个最适合我们使用

多谢各位

更新2: 在回答James Massey的评论时添加了更多信息:

这些是我的:datasource、sessionFactory、transactionManager和categoryDAO sessionFactory分配:

<!-- ========================= DATA ACCESS OBJECT DEFINITIONS ======================== -->

<bean id="dataSource"
      class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>java:comp/env/jdbc/catWDB</value>
    </property>
</bean>


<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref local="dataSource"/>
    </property>
    <property name="configLocation" value="classpath:hibernate.cfg.xml" />

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.connection.pool_size">3</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.max_fetch_depth">1</prop>

        </props>
    </property>
</bean>


<!---->
<bean id="transactionManager" lazy-init="true"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
        <ref local="sessionFactory"/>
    </property>

</bean>



<bean id="categoryDAOTarget" class="com.bamboo.catW3.DAO.impl.CategoryDAOImpl">
    <property name="sessionFactory">
        <ref local="sessionFactory"/>
    </property>
</bean>

java:comp/env/jdbc/catWDB
org.hibernate.dialogue.mysqldialogue
3.
真的
1.

我认为您应该使用
@PersistenceContext
注释从Spring上下文获取
EntityManager
,并使用
@Transactional
注释驱动您的事务。这样,您就不必担心手动关闭Hibernate会话,连接数也不会增加,直到有太多的连接。

问题不在于会话,而在于连接池,会话管理正确,但JDBC层的连接池没有关闭连接

这些是我为修复它们所做的事情

JDBC上下文配置

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/" override="true" reloadable="false" swallowOutput="false">
    <Resource name="jdbc/catWDB" auth="Container" type="javax.sql.DataSource"
              driverClassName="com.mysql.jdbc.Driver"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              url="@URL@"
              username="@USERNAME@"
              password="@PASSWORD@"
              maxActive="200"
              maxIdle="50"
              minIdle="10"
              suspectTimeout="60"
              timeBetweenEvictionRunsMillis="30000"
              minEvictableIdleTimeMillis="60000"
              validationQuery="select 1"
              validationInterval="30000"
              testOnBorrow="true"
              removeAbandoned="true"
              removeAbandonedTimeout="60"
              abandonWhenPercentageFull="10"
              maxWait="10000"
              jdbcInterceptors="ResetAbandonedTimer;StatementFinalizer"
            />
</Context>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
            </props>
        </property>
</bean>
1.-将JDBC连接工厂从tomcat的旧BasicDataSourceFactory更改为tomcat的新DataSourceFactory

2.-根据本文调整了JDBC设置:

会话工厂xml配置

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/" override="true" reloadable="false" swallowOutput="false">
    <Resource name="jdbc/catWDB" auth="Container" type="javax.sql.DataSource"
              driverClassName="com.mysql.jdbc.Driver"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              url="@URL@"
              username="@USERNAME@"
              password="@PASSWORD@"
              maxActive="200"
              maxIdle="50"
              minIdle="10"
              suspectTimeout="60"
              timeBetweenEvictionRunsMillis="30000"
              minEvictableIdleTimeMillis="60000"
              validationQuery="select 1"
              validationInterval="30000"
              testOnBorrow="true"
              removeAbandoned="true"
              removeAbandonedTimeout="60"
              abandonWhenPercentageFull="10"
              maxWait="10000"
              jdbcInterceptors="ResetAbandonedTimer;StatementFinalizer"
            />
</Context>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
            </props>
        </property>
</bean>
3.-从会话工厂配置中删除了此行:

<prop key="hibernate.max_fetch_depth">1</prop>
1
我的配置就是这样结束的:

JDBC上下文配置

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/" override="true" reloadable="false" swallowOutput="false">
    <Resource name="jdbc/catWDB" auth="Container" type="javax.sql.DataSource"
              driverClassName="com.mysql.jdbc.Driver"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              url="@URL@"
              username="@USERNAME@"
              password="@PASSWORD@"
              maxActive="200"
              maxIdle="50"
              minIdle="10"
              suspectTimeout="60"
              timeBetweenEvictionRunsMillis="30000"
              minEvictableIdleTimeMillis="60000"
              validationQuery="select 1"
              validationInterval="30000"
              testOnBorrow="true"
              removeAbandoned="true"
              removeAbandonedTimeout="60"
              abandonWhenPercentageFull="10"
              maxWait="10000"
              jdbcInterceptors="ResetAbandonedTimer;StatementFinalizer"
            />
</Context>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
            </props>
        </property>
</bean>

会话工厂xml配置

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/" override="true" reloadable="false" swallowOutput="false">
    <Resource name="jdbc/catWDB" auth="Container" type="javax.sql.DataSource"
              driverClassName="com.mysql.jdbc.Driver"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              url="@URL@"
              username="@USERNAME@"
              password="@PASSWORD@"
              maxActive="200"
              maxIdle="50"
              minIdle="10"
              suspectTimeout="60"
              timeBetweenEvictionRunsMillis="30000"
              minEvictableIdleTimeMillis="60000"
              validationQuery="select 1"
              validationInterval="30000"
              testOnBorrow="true"
              removeAbandoned="true"
              removeAbandonedTimeout="60"
              abandonWhenPercentageFull="10"
              maxWait="10000"
              jdbcInterceptors="ResetAbandonedTimer;StatementFinalizer"
            />
</Context>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
            </props>
        </property>
</bean>

org.hibernate.dialogue.mysqldialogue
假的
3.

如何打开/关闭Hibernate会话?您是使用
@PersistenceContext
从Spring获取
EntityManager
,还是手动打开/关闭Hibernate会话?如果您手动打开Hibernate会话,您确实需要自己关闭它。我不确定,因为应用程序该部分的原始设计者离开了,我认为我们在AOP配置中使用了这个类来处理它:org.springframework.transaction.interceptor.TransactionProxyFactoryBean,但我不知道如何检查你问的问题。你能帮我吗?谢谢。检查是否有手动使用的Hibernate
Session
对象,例如
Session sess=factory.openSession()谢谢你,mithridas,你的评论非常有用,我根据你的评论更新了问题库,因为它的信息太多了。你能发布你的会话工厂和事务管理器配置吗。或者您没有使用Spring的会话工厂和事务管理器?不使用这些对象的缺点是手动管理会话很困难,并且容易出现您所描述的问题。如果您使用的是这些对象,那么这就是您的配置问题。谢谢mithridas,我将使用本文尝试您的建议:,并在生产环境中测试后返回。您好,我添加了您的建议,但问题不在于会话,而在于连接池,即正确管理的会话,但是jdbc层中的连接池没有关闭连接。您的jdbc连接与server.xml文件中的服务器连接相比如何-尝试比较的jdbc与服务器连接的比率以比较指标。