【问题标题】:Throws exception and return from finally - Tomcat hangs抛出异常并从 finally 返回 - Tomcat 挂起
【发布时间】:2013-08-19 20:15:40
【问题描述】:


最近在看tomcat服务器的频繁挂起,遇到了一些代码的某些部分频繁抛出的异常。

当我检查代码时,它看起来像这样

public static String doSomething() {
    String returnVakue = "default value";

    try {
        ResultSet rs = getMyResultSet(); 

        rs.first(); 
        returnValue = rs.getString("my_field"); // Note that Exception happens at times when the ResultSet is empty

    } catch (Exception e) {
        throw new Exception(e);
    } finally {
        return returnValue;
    }

}

虽然我知道同时抛出异常和返回是完全可以的,但我想知道这是否会导致 tomcat 中的任何类型的泄漏。性能是否存在任何潜在风险。 ?但是,我的调用者函数此时会停止执行。对此有何看法?对GC有影响吗?

编辑:注意:我知道如何更正此代码。请分享您的看法,这是否可能导致 tomcat 挂起。

【问题讨论】:

  • @StormeHawke 这里不会抛出异常,方法会返回returnValue,异常被丢弃。
  • @Akhil 这是实际的完整代码吗?它不会 close() ResultSet,也可能不是 JDBC 连接。这会堆积起来,最终会耗尽内存或降低数据库速度。
  • @nos 是的,我已经检查过了。我的连接管理在不同的层中处理,该层负责所有与 JDBC 相关的资源。这是一个伪代码..不是实际的。
  • @StormeHawke 正是……这就是我要提出的观点。任何人都可以清楚地定义在这种情况下会发生什么。这可以将tomcat推到无限状态吗?
  • @StormeHawke 如前所述,异常被吞没。该函数将正常返回。它将分配给调用者。这是很好定义的。参见例如stackoverflow.com/questions/5126455/…

标签: java mysql performance tomcat exception-handling


【解决方案1】:

首先检查返回的ResultSet是否为空。

while( rs.next() ) {
    // ResultSet processing here
    // Result set is not empty
}

在我看来,抛出异常是您的决定,但最终您应该进行清理,例如关闭连接。

如果未关闭打开连接将导致 tomcat 挂起,因为到达服务器的新请求将等待连接可用。

Java 中引用的任何对象都不会被垃圾回收,在您的情况下,如果连接没有关闭,那么这些对象将不会被垃圾回收。

干杯!!

【讨论】:

    【解决方案2】:

    如果查询需要很长时间,则不是 JDBC 的问题。数据库负责。当然,如果 JDBC 使用得当的话。另一方面,如果您使用简单的 JDBC,最好在您的应用程序中添加一个层 DAO。

    public class UserDAO extends DAO {
    
        private static final String FIND_BY_PK_SQL = 
            "SELECT mail, password " +
            "  FROM user WHERE mail = ?";
    
        public User findByPk(final String mail) throws DAOException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = getConnection();
                ps = conn.prepareStatement(FIND_BY_PK_SQL);
                ps.setString(1, mail);
                rs = ps.executeQuery();
                if (rs.next()) {
                    return fill(rs);
                }
                return null;
            } catch (final SQLException e) {
                throw new DAOException(e);
            } finally {
                DbUtils.closeQuietly(conn, ps, rs);
            }
        }
    
        private User fill(final ResultSet rs) throws SQLException {
            final User user = new User();
            user.setMail(rs.getString("mail"));
            user.setPassword(rs.getString("password"));
            return user;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      相关资源
      最近更新 更多