dbcp释放不了mysql链接,相同的旧故事:Tomcat DBCP + MySQL,MySQLNonTransientConnectionException:连接关闭后不允许进行任何操作...

I examined related questions here on this topic, and also googled for some time. Still seems I don't understand something crytical in Tomcat's DBCP configuration or mechanics.

I got Tomcat 6, DBCP resource configured in server.xml:

type="javax.sql.DataSource"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://myhost:3306/mydb?autoReconnectForPools=true&useUnicode=true"

username="user"

password="password"

validationQuery="SELECT 1"

testOnBorrow="true"

testWhileIdle="true"

timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="60000"

maxActive="20" maxWait="20000" maxIdle="10"

removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" />

Also I looked for mysql's wait_timeout and it is default 28800.

In summary I tried several options, but seems the problem is that mysql connections hit 28800 seconds of being idle and server closes them. I thought that pool should somehow handle this situation with validationQuery and testOnBorrow, but seems I'm wrong.

If I use autoReconnect in url after idle period My first query attempt results in "...CommunicationsException: The last packet successfully received from the server was 157,493,261 milliseconds ago." but after this it works normal.

If I use autoReconnectForPools in url or just don't use it - after idle period (8 hours) I got everytime ".MySQLNonTransientConnectionException: No operations allowed after connection closed".

In both cases things go smoothly while app has load. So, I concluded that connections was closed from side of mysql.

Help, what have I missed? I'd like to solve this problem without changing wait_timeout in Mysql. Goal - stable app which may survive idle times if it occur :)

解决方案

I thought a bit, and decided to leave this question to be, though problem was not in Tomcat DBCP at all. My decision is motivated by the fact that I found quite a number of similar questions, and many of them unanswered, and never found a clue for what might have been going on. So, I leave a message here just as a warning for anyone suddenly walking the same path:

The problem was that I had a resource using database which was initialized just once, like:

class MyClass {

private MyResource res = null;

private MyResource getMyResource() {

if (res == null) res = new MyResource(getConnection());

return res;

}

private Connection getConnection() {

....

con = dataSource.getConnection();

....

return con;

}

}

When my app was in Servlet it led to the situation where instance of MyResource were the only one, and had connection open. So, when MySQL server kill the expired connection my app would get exception about timeout on first query, but owing to autoReconnect for subsequent queries connection will be alive again. Pool just didn't touched connection because it had never been released.

Finally I realized it, and fixed by changing getMyResource to:

private MyResource getMyResource() {

return new MyResource(getConnection());

}

In my case it was reasonable. After this change all things started to work as expected.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值