gpt4 book ai didi

mysql - 我的 spring+hibernate 应用程序没有关闭 jdbc 连接

转载 作者:行者123 更新时间:2023-11-29 01:40:47 25 4
gpt4 key购买 nike

我在生产环境中有一个 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 天到现在监控连接的 appdynamics 的图像

app Dynamics image

这是我在 catalina.out 日志文件中得到的错误的摘录:

type Exception report

message Request processing failed; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open connection

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open connection org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:932) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:816) javax.servlet.http. . . .

root cause

org.hibernate.exception.JDBCConnectionException: Cannot open connection org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:99) org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52) org.hibernate.jdbc.ConnectionManager. . . .

root cause

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Too many connections sun.reflect.GeneratedConstructorAccessor67.newInstance(Unknown Source) sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) java.lang.reflect.Constructor.newInstance(Constructor.java:513) com.mysql.jdbc.Util.handleNewInstance(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;
}

Category 域对象映射如下:

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

所以我的猜测是,考虑到 mithridas 的评论,我正在手动使用 hibernate session ,我需要用这样的东西关闭它们:

this.getSession().clear();

或者我可以实现@PersistenceContext。谁能指导我使用此实现,以便我评估哪种最适​​合我们使用?

谢谢。

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

这些是我的:数据源、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>

最佳答案

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

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

JDBC 上下文配置

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

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

session 工厂xml配置

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

<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>

session 工厂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>

关于mysql - 我的 spring+hibernate 应用程序没有关闭 jdbc 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23480106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com