4

最近,我的tomcat开始挂了。这些请求从未得到答复。我发现这是由于连接从未返回到连接池。

我用 c3p0 和休眠,数据库是 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 说它支持与 InnoDB 的事务

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

请让我知道开始交易时出了什么问题,即使我正在使用 finally 并且没有抛出异常。

4

2 回答 2

4

一些调试它的建议

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

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

  • 还可以尝试休眠中的事务超时选项。可以设置 tx.setTimeout(20) 并使用超时数,看看是否有一些查询超时。

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

对代码的小改进

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

  • 还为会话关闭添加了空检查。您可能已经知道 finally 可能无法完全执行的一个条件 - 如果在 finally 块中引发另一个异常。目前它可能不适用于您的代码,但是如果您在 finally 块中添加多行,请确保覆盖所有异常以便下一行可以执行。

  • 另一个建议是缩小事务本身的范围。查看代码,您可能仅在找不到 uid 的情况下才需要事务。如何限制 if(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;
}
于 2013-10-14T16:53:58.223 回答
2

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

事务.commit();

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

于 2014-05-07T07:01:05.067 回答