简体   繁体   English

Tomcat连接池被放弃的问题

[英]Tomcat Connection Pool abandoned issue

I'm struggling with a Tomcat connection pool error.The below error is thrown at runtime after running a simple stored procedure that generates a String value. 我正在努力解决Tomcat连接池错误。运行生成字符串值的简单存储过程后,在运行时会抛出以下错误。

WARNING: Connection has been abandoned PooledConnection[ConnectionID:45 ClientConnectionId: 7817280c-3f7e-4239-a009-3aedd0a855e8]:java.lang.Exception
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1096)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:799)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:648)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:200)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
    at util.ThreadLocalUtil.getConnection(ThreadLocalUtil.java:55)
    at webapp.dao.WebApplicationDAO.getConnection(WebApplicationDAO.java:30)
    at webapp.dao.AccountDAO.generateAccountId(AccountDAO.java:827)
    at webapp.bo.Account.generateUserAccountId(Account.java:285)
    at webapp.actions.AddUserAccountUNZAction.execute(AddUserAccountUNZAction.java:79)
    at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
    at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
    at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)

My knowledge of that error is that a connection was opened and not closed. 我对该错误的了解是连接已打开但未关闭。 The connection is opened when running the stored proc in the account dao. 在帐户dao中运行存储的proc时,将打开连接。 Below is the block of code which calls the stored procedure. 下面是调用存储过程的代码块。

Connection conn = null;
    CallableStatement stmt = null;
    ResultSet rs = null;
    try {

        conn = getConnection();
        stmt = conn.prepareCall(sqlWebAppGenerateUserId);
        stmt.setString(1, base);
        rs = stmt.executeQuery();
        String res = null;
        if (rs.next()) {
            res = rs.getString(1);
        }

        if (res == null) {
            throw new RuntimeException("Failed to generate user id.");
        }

        return res;
    } catch (SQLException e) {
        LOG.error("{}", e);
        throw new RuntimeException(e);
    }finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                LOG.error(e.getMessage(), e);
            }
        }
        if (rs != null) {
            try {
                rs.close();
                conn.close();
            } catch (SQLException e) {
                LOG.error(e.getMessage(), e);
            }
        }

    }

As you can see, I'm using a finally block to close the connection etc. 如您所见,我正在使用finally块来关闭连接等。

I'm at a loss to explain the reason why the error is being thrown still and as to how I can debug and solve this issue. 我无所适从地解释了为什么仍然引发错误以及如何调试和解决此问题的原因。 Any help would be greatly appreciated 任何帮助将不胜感激

You close conn only if rs != null , meaning that every time a query fails the connection won't be closed. 仅当rs != null时才关闭conn ,这意味着每次查询失败都会关闭连接。

I also recommend switching to try-with-resources instead of writing clumsy finally blocks which may cause bugs. 我还建议切换到try-with-resources,而不是编写可能导致bug的笨拙的finally块。

What @Kayaman said. @Kayaman说什么。 Also if the statement execution takes longer than removeAbandonedTimeout this can happen. 同样,如果语句执行花费的时间超过removeAbandonedTimeout则可能会发生这种情况。

@Kayaman and @Gorazd thank you for the advice. @Kayaman和@Gorazd谢谢您的建议。 The issue with down to missing jar files in the tomcat lib folder. 导致tomcat lib文件夹中缺少jar文件的问题。 More specifically mail-1.4.jar. 更具体地说,是mail-1.4.jar。

As this jar file was missing, a function that sends emails failed. 由于缺少该jar文件,因此发送电子邮件的功能失败。 Previous to the call to send the mail, connection.autocommit is set to true. 在发送邮件的呼叫之前,将connection.autocommit设置为true。 After the mail sends it will set autocommit back to false. 邮件发送后,它将自动提交设置回false。 This to me looks like where the abandoned error was occurring from. 对我来说,这似乎是发生废弃错误的地方。

When looking through logs file I found the mail sending error. 浏览日志文件时,我发现邮件发送错误。 This was in actual fact the true error whereas the abandoned error can be looked at as a red herring. 实际上,这是真正的错误,而被遗弃的错误可以看作是红色鲱鱼。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM