c3p0说 – “java.lang.Exception:DEBUG ONLY:过期资源检出堆栈跟踪”启动一个hibernate事务

最近,我的tomcat开始挂起。 这些请求从未得到回复。 我发现这是因为连接永远不会返回到连接池。

我使用了c3p0和hibernate,数据库是mysql 5.5

为了调试连接泄漏,我在hibernate.cfg.xml添加了以下属性

  30 true 

添加后,在日志中说:

 [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说它支持与InnoDB的交易

由于上述错误,我没有返回连接,然后他们堆积使应用程序无响应。

请让我知道在开始交易时出了什么问题,即使我最终都在使用,也没有例外。

一些调试它的建议

  • 史蒂夫在评论中提到。 尝试查看删除unreturnedConnectionTimeout选项时会发生什么。

  • 可能是你的查询花了太长时间。 尝试在代码上记录一些性能统计信息,并查看查询所花费的时间。 可能是您需要调整查询。 而且对于短期而言,您还可以将unreturnedConnectionTimeout增加到超过查询的响应时间。

  • 还可以在hibernate中尝试事务超时选项。 可以设置tx.setTimeout(20)并播放超时数字并查看某些查询是否超时。

  • 您可能还想使用一些分析工具。 如果您的Java版本受支持,请尝试使用VisualVM 。 否则(如果在linux或mac上)你可能想在旧版本的java上尝试Java Debugging命令 。 其中一些命令也可以从JDK获得。

对代码的小改进

  • 不确定它是否真的能解决您的问题,但是您可能希望在exception块中为事务添加回滚。 为tx.close添加了另一个try catch以避免另一个exception。

  • 还为会话关闭添加了空检查。 您可能已经知道最终可能无法完全执行的一个条件 – 如果在finally块中抛出另一个exception。 目前它可能不适用于您的代码,但是如果您在finally块中添加多行,请确保涵盖任何exception,以便下一行可以执行。

  • 还有一个建议是减少交易本身的范围。 查看代码似乎只有在找不到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; } 

出现此错误的原因之一是当您不确定时

器transaction.commit();

不是这个问题的答案,但是在谷歌搜索错误后,忘记提交的人也将登陆此页面