最近,我的tomcat开始挂起。这些请求从未得到回复。我发现这是因为连接永远不会返回到连接池。
我使用了c3p0和hibernate,数据库是mysql 5.5
为了调试连接泄漏,我在hibernate.cfg.xml
<property name="hibernate.c3p0.unreturnedConnectionTimeout">30</property>
<property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces">true</property>
添加后,在日志中说:
[2013-10-12 23:40:22.487] [ INFO] BasicResourcePool.removeResource:1392 - A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@1f0c0dd
[2013-10-12 23:40:22.487] [ INFO] BasicResourcePool.removeResource:1395 - Logging the stack trace by which the overdue resource was checked-out.
java.lang.Exception: DEBUG ONLY: Overdue resource check-out stack trace.
指向at dao.DAOBasicInfo.getBean(DAOBasicInfo.java:69)
public static Basicinfo getBean(Integer iduser) {
Basicinfo u = null;
Session sess = NewHibernateUtil.getSessionFactory().openSession();
try {
Transaction tx = sess.beginTransaction(); //line 69
Query q = sess.createQuery("from Basicinfo where iduser=" + iduser);
u = (Basicinfo) q.uniqueResult();
if (u == null) {
u = new Basicinfo();
u.setIduser(iduser);
}
tx.commit();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
sess.close();
}
return u;
}
我交叉检查了Mysql says it supports transactions with InnoDB
由于上述错误,我没有返回连接,然后他们堆积起来使应用无响应。
请让我知道开始交易时出了什么问题,即使我终于使用了,也没有例外。
答案 0 :(得分:4)
调试它的一些建议
史蒂夫在评论中提到。尝试查看删除unreturnedConnectionTimeout选项时会发生什么。
可能是您的查询花了太长时间。尝试在代码上记录一些性能统计信息,并查看查询所花费的时间。可能是您需要调整查询。而且对于短期而言,您还可以将unreturnedConnectionTimeout增加到超过查询的响应时间。
还在hibernate中尝试事务超时选项。可以设置tx.setTimeout(20)并播放超时数字并查看某些查询是否超时。
您可能还想使用一些分析工具。如果您的Java版本受支持,请尝试VisualVM。否则(如果在linux或mac上)你可能想在旧版本的java上尝试Java Debugging commands。其中一些命令也可从JDK获得。
代码的小改进
不确定它是否真的能解决您的问题,但是您可能希望在异常块中为事务添加回滚。为tx.close添加了另一个try catch以避免另一个异常。
还为会话关闭添加了空检查。您可能已经知道最终可能无法完全执行的一个条件 - 如果在finally块中抛出另一个异常。目前它可能不适用于您的代码,但是如果您在finally块中添加多行,请确保涵盖任何异常,以便下一行可以执行。
还有一个建议是减少交易本身的范围。查看代码,似乎只有在找不到uid的情况下才需要该事务。如果(u == null)阻止,如何限制内部的事务代码。不确定是否有帮助但你不需要阅读交易。
以下是我的示例代码
public static Basicinfo getBean(Integer iduser) {
Basicinfo u = null;
Transaction tx = null;
Session sess = NewHibernateUtil.getSessionFactory().openSession();
try {
Query q = sess.createQuery("from Basicinfo where iduser=" + iduser);
u = (Basicinfo) q.uniqueResult();
if (u == null) {
tx = sess.beginTransaction(); //line 69
u = new Basicinfo();
u.setIduser(iduser);
tx.commit();
}
} catch (Exception ex) {
ex.printStackTrace();
if(tx != null) {
try {
tx.rollback();
} catch(Exception e){e.printStackTrace;}
}
} finally {
if(sess!=null) {
sess.close();
}
}
return u;
}
答案 1 :(得分:2)
出现此错误的原因之一是您不确定
器transaction.commit();
不是这个问题的答案,但忘记提交的人也会在搜索错误后登陆此页面