当前位置: 首页 > 知识库问答 >
问题:

我的spring hibernate应用程序不会关闭jdbc连接

子车飞鹏
2023-03-14

我有一个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>

这是从3天到现在,应用程序监控连接的图像

这是我在卡塔琳娜号上所犯错误的摘录。输出日志文件:

类型异常报告

消息请求处理失败;嵌套异常org.hibernate.exception.JDBCConnectionExc0019:无法打开连接

描述服务器遇到了一个内部错误,使其无法完成此请求。

例外

org.springframework.web.util.NestedServletExc0019:请求处理失败;嵌套异常org.hibernate.exception.JDBCConnectionExc0019:无法打开连接org.springframework.web.servlet.FrameworkServlet.process请求(FrameworkServlet.java:932)org.springframework.web.servlet.FrameworkServlet.do获取(FrameworkServlet.java:816)javax.servlet.http....

根本原因

组织。冬眠例外JDBCConnectionException:无法打开连接组织。冬眠例外SQLStateConverter。convert(sqlstatecoverter.java:99)org。冬眠例外JDBCExceptionHelper。转换(jdbceptionhelper.java:66)组织。冬眠例外JDBCExceptionHelper。convert(jdbceptionhelper.java:52)org。冬眠jdbc。连接管理器。

根本原因

通用域名格式。mysql。jdbc。例外情况。jdbc4。MySQLNonTransientConnectionException:连接太多。反映生成的构造函数或Accessor 67。newInstance(未知源)sun。反映删除构造函数或AccessorImpl。newInstance(DelegatingConstructorAccessorImpl.java:27)java。朗。反思。构造器。newInstance(Constructor.java:513)com.mysql。jdbc。Util。HandleneInstance(Util.java:406)com.mysql。jdbc。Util。getInstance(Util.java:381)com.mysql。jdbc。SQLError。

更新

public Category findByIdByApp(Integer id, int appListId) throws DataAccessException {

       Criteria criteria = getSession().createCriteria(Category.class,"category")
                .createAlias("appList", "app")
                .add(Restrictions.and(Restrictions.eq("category.categoryId", id), Restrictions.eq("app.appListId", appListId)));
          List result=criteria.list();

        if(result.size()==1)

                return (Category) result.get(0);
         else
                return null;
    }

类别域对象映射如下:

@Entity
@Table(name = "category")
public class Category implements Comparable, Serializable {

所以我的猜测是,考虑到米特里达斯的评论,我正在手动使用hibernate会话,我需要用如下方式关闭它们:

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>

共有2个答案

尤俊誉
2023-03-14

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

邓仲卿
2023-03-14

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

这些是我为了修复它们而做的事情。

JDBC上下文配置

1.-将JDBC连接工厂从tomcat的旧BasicDataSourceFactory更改为tomcat的新DataSourceFactory

2.-根据本文调整JDBC设置:http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency

会话工厂xml配置

3.-从会话工厂配置中删除了这一行:

<prop key="hibernate.max_fetch_depth">1</prop>

这就是我的配置结果:

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>

会话工厂xml配置

<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>
 类似资料:
  • 嗨,我只知道这是一个古老的问题,但今天只是好奇。正如我们所知connection.close也会关闭preared语句(如果我错了请纠正我)。但是如果我关闭连接然后关闭preared语句会怎样 我会得到一个空指针异常吗? 有人说这取决于jvm的速度。有时,ps.close()会在conn.close完成其工作之前运行并首先关闭,因此您不会得到null指针。 为了测试它,我修改了代码 但是我没有得到

  • 我试图重新创建Connect四,我成功了。但我想通过频繁地切换颜色,给玩家一个获胜的四张光盘在哪里的指示。我对线程和编程中的时间概念是新的。 我也成功地给了用户这个指示,但是在关闭应用程序之后,控制台仍然会给出输出,也是在使用SetonCloserEquest时。 代码如下:

  • 我做了一个jsf应用程序。这个应用程序有一个包含开始、停止按钮的菜单。当按下开始时,应用程序开始从网站获取数据,并更新其数据库。应用程序还有更新过程的进度条。但是,这个过程需要很长时间才能完成。我希望当我关闭浏览器时,它应该继续更新数据库。此外,当我再次打开它时,我应该得到以前的状态。然而,这并没有发生。当我关闭浏览器时,应用程序也关闭了。我该怎么办? 谢谢。

  • 问题内容: 我最近开始在应用程序中使用hibernate和c3p0作为ORM。但是,当我关闭会话工厂时,连接池不会自行关闭!这是我的应用程序中 唯一 可以进行会话操作的地方。 这是我的配置文件 请注意,空闲连接非常短的原因是它是我尚未通过集成测试的唯一方法。他们经常打开和关闭会话工厂,因此我总是用尽所有连接。正如我们在项目开始时一样,从长远来看,我认为这不是一个非常可持续的策略。 需要注意的“有趣

  • 编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将帮助其他人回答问题。 我的主要活动: 我的清单: 我的下一个代码: 下一个: 对于堆栈跟踪排序: 我的xml文件显示第一页: 要显示第二个选项卡的我的xml文件: 最后我想告诉你,我已经坚持了三天了。请更正此代码。中的“TabListener”接口不可用。但忽略它,在几毫秒后运行我的应用程序,然后“很遗憾,你的应用程序停止工作