我在Struts2.0 + Spring2.0 + hibernate3.2的应用中采用了proxool 数据库连接池。
proxool.xml的配置如下:
<?xml version="1.0" encoding="utf-8"?>
test
jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf-8
com.mysql.jdbc.Driver
select CURRENT_DATE
90000
5
100
10
在applicationContext.xml中
<!-- Hibernate-Spring配置 -->
com/test/User.hbm.xml
org.hibernate.dialect.MySQLDialect
false
true
after_statement
true
org.hibernate.cache.EhCacheProvider
org.hibernate.connection.ProxoolConnectionProvider
proxool.xml
test
MySqL 的 my.ini 配置参数
max_connections=500
interactive_timeout=10000000
wait_timeout=10000000
proxool 的 maximum-connection-lifetime(连接最大生命时间)默认4小时,发现每隔4个小时,通过show status命令查看MySQl 的Connections 增加10个,很快就会到达max_connections的最大限制,虽然可以把max_connections设置为16000,但是这只是延长出问题的时间而已。请各位遇到这样情况的朋友指导如何解决?
MySQL 版本5.0和4.1都试过,proxool 版本为 proxool-0.9.0RC3。
[b]问题补充:[/b]
蔡华江:谢谢指点。我在数据库的查询、更新等方面都是通过hibernate来完成的,如查询用户
public User findUserByUsername(String username)
{
String queryStr=PropertyOwner.getKeyValue("getuserwithname");
Session session = this.getSession();
Query query=getQuery(queryStr,session);
query.setString("username", username);
if(query.list().size()>0)
{
User tmp=(User)query.list().get(0);
this.closeSession(session);
return tmp;
}
else
{ this.closeSession(session);
return null;
}
}
在程序的最后都有this.closeSession(session);这样的语句,难道数据连接没有关闭?
[b]问题补充:[/b]
现在我怀疑是 this.closeSession(session); 没有关闭连接。因为Session session = this.getSession(); 利用getSession强制获得了Hibernate的 Session,这个Session可能是当前事务中之前使用过的,或者可能是一个新的,并不在当前事务中,Spring只对当前事务中的Session 进行关闭。参考“spring整合hibernate关于session的管理”(http://solodu.iteye.com/blog/454469),我修改Session session = super.getSession(true);运行10分钟后还是递增连接。说明还有其他的数据库连接没有释放。查看Proxool的监控界面可以看到连接情况0 (active), 10 (available), 100 (max)。
我怀疑一个定时保存的地方有问题
try { otherDAO.updataOrSave(tmpp);
} catch (Exception e) { }
......>跟踪
public void updataOrSave(T domainObject) throws Exception
{
saveOrUpdate((Object)domainObject);
}
......>继续跟踪
protected void saveOrUpdate(final Object obj)throws Exception {
run (
new TransactionRunnable () {
public Object run (Session s) {
saveOrUpdate(obj, s);
return null;
}
});
}
......>继续跟踪
protected void saveOrUpdate(Object obj, Session s) {
s.saveOrUpdate(obj);
}
请问上述代码有问题吗?
[b]问题补充:[/b]
现在我把定时保存部分关闭了,照样有此问题。
[b]问题补充:[/b]
经过多次试验,增加连接的地方是类似这样的hibernate的操作
public History queryHistory(String queryStr,String entity,Date time)
{
Session session = this.getHibernateTemplate().getSessionFactory().openSession();//该句照样增加连接数
//getSession();//该句照样增加连接数
Query query=super.getQuery(queryStr,session);
int size=query.list().size();
if(size>0)
{
History temp=(History)query.list().get(0);
session.close();
return temp;
}
else
{
session.close();
return null;
}
}
[b]问题补充:[/b]
现在问题是Proxool连接池里的连接ID老是递增(通过Proxool监控界面看),连接数是没有超过最大连接。请问各位好手如何解决啊?
[b]问题补充:[/b]
这个问题竟然是我的理解错了。
MySQL的SHOW STATUS提供服务器的状态信息:
Connections 试图连接MySQL服务器的次数,是不断增加,不是真正的目前连接数(与MySqL 的 my.ini 配置参数 max_connections无关,好多人都理解错误)。
真正有用的是下述几个
Threads_created 表示创建过的线程数,该值太大,就要增加my.cnf中thread_cache_size的值
Threads_connected 当前打开的连接的数量。
Threads_running 不在睡眠的线程数量。
Aborted_clients 由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。
Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。
感谢蔡华江的指导。