spring dbcp连接不释放

bearcat 发布于 2013/11/19 10:12
阅读 12K+
收藏 0

问题描述

这个spring配置,在使用过程中,基本上没插入200条数据后,通过mysql或netstat就可看到数据库连接达到10个,

并且mysql里面全部都是sleep状态。连接并没有释放,在等几十条后就出现异常。


dbcp配置
<bean id="writeSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value=jdbc:mysql://db.test.com:3306/TEST_DB" />
<property name="username" value="root" />
<property name="password" value="abc123" />
<property name="maxIdle" value="30" />
<property name="minIdle" value="5" />
<property name="maxWait" value="30000" />
<property name="maxActive" value="10" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="select 1" />
</bean>


spring 注解事务

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />


以下为stack信息

### Error querying database.  Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, cause: Timeout waiting for idle object, cause: Timeout waiting for idle object
### The error may exist in configure/mybatis/User.xml
### The error may involve novel.Novel_read
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, cause: Timeout waiting for idle object, cause: Timeout waiting for idle object
        at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23) ~[mybatis-3.2.3.jar:3.2.3]
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:107) ~[mybatis-3.2.3.jar:3.2.3]
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98) ~[mybatis-3.2.3.jar:3.2.3]
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:62) ~[mybatis-3.2.3.jar:3.2.3]
        at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source) ~[na:na]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_45]
        at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_45]
        at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358) ~[mybatis-spring-1.2.1.jar:1.2.1]
        ... 45 common frames omitted
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, cause: Timeout waiting for idle object, cause: Timeout waiting for idle object


mysql状态采样(其余一样,共10个) 

3 | root | localhost:34779 | test_db | Sleep | 659 | | NULL | 

网络状态采样(其余一样,共10个) 

tcp 0 0 ::ffff:127.0.0.1:34941 ::ffff:127.0.0.1:3306 ESTABLISHED 23223/java


使用c3p0和tomcat连接池均测试过,问题依旧存在。

c3p0配置如下:

<bean id="writeSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://db.test.com:3306/TEST_DB" />
<property name="user" value="root" />
<property name="password" value="abc123" />
<property name="maxPoolSize" value="10" />
<property name="minPoolSize" value="5" />
<property name="initialPoolSize" value="5" />
<property name="acquireIncrement" value="2" />
<property name="maxIdleTime" value="3000" />
</bean>

软件版本

mysql版本5.6.14

mysql-connector 5.1.22

执行的插入SQL

<insert id="USER_create" parameterType="User" useGeneratedKeys="true" keyProperty="id">
insert into LT_USER (
NAME,
DESCN,
IMG,
CATEGORY_ID,
IS_FINISH,
CREATE_DATE,
STATUS
) values (
#{name, jdbcType=VARCHAR},
#{descn, jdbcType=VARCHAR},
#{img, jdbcType=VARCHAR},
#{categoryId, jdbcType=NUMERIC},
#{isFinish},
#{createDate},
#{status}
)
</insert>


@Repository
public class UserDao extends SqlSessionDaoSupport {
    public long create(final String sqlId, final Parameter parameter) {
        return this.getSqlSession().insert(sqlId, parameter.getCriteria());
    }
}

事务配置

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:configure/mybatis/Configuration.xml" />
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

加载中
0
b
bearcat

确实是spring事务的问题,我将事务控制的代码删除,不调整其他地方,则全部正常。上面的问题均未在出现过。但不知道如何修改。没有看到事务控制有错误的地方。

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

刘志成
刘志成
回复 @bearcat : 汗,这个确实要注意了,自己代码的问题
b
bearcat
回复 @刘志成 : 找到原因了。不是配置的问题。是因为程序里面有一段代码执行的时候是伪死循环(执行几万遍数据库查询后会退出),导致所有线程阻塞,不能进入。
刘志成
刘志成
回复 @bearcat : 那就是spring的問題了 一就是你的xml配置出了問題 或者spring 包的問題
b
bearcat
回复 @刘志成 : 只要去掉<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />这行代码就可以正常运行。不在出现这个错误。
b
bearcat
回复 @刘志成 : 一样的效果。问题依旧。
下一页
0
刘志成
刘志成
请列出你的插入数据那段代码,可能是事务的问题 或者是iBATIS的问题
b
bearcat
非常怀疑是事务配置方面的问题, 我测试了事务是可以回滚的。但是看起来像数据库连接没有释放。 就一个线程不停的插入数据(300毫秒间隔)都会导致这个问题。
0
温佐镜
温佐镜
你开启注解事务,检查下调用的的方法是否有事务?(@Transactional)
b
bearcat
基于方法级的
b
bearcat
有的, @Transactional(propagation=Propagation.REQUIRED)
0
b
bearcat

删除事务管理后,应用恢复正常。mysql显示状态不在是sleep,全部为正常的query和insert

采样如下:

| 258 | root | localhost:43367 | test_db | Query   |    0 | Sending data   | select * from USER


                 WHERE  SPELL = 'tm'   |


0
安世博
安世博
dbcp的问题,换成proxool
返回顶部
顶部