抛出异常会挂起流量控制

时间:2011-01-05 18:27:05

标签: java exception-handling

最近,我一直面临在JDBC主题中抛出异常的问题。

我使用2个同步方法同步Connection对象:getConnection()和releaseConnection()。然后是另一种从数据库中删除行的方法,如下所示:

public void removeItem(int itemID) throws ItemNotFound {
    PreparedStatement ps = null;
    String query = "DELETE * FROM Student.Book WHERE id = ?";
    getConnection();
    try {
      ps = con.prepareStatement(query);
      ps.setInt(1, bookID);
      ps.executeUpdate();
    } catch (SQLException sqle) {
      this.close(null, null, ps);  // method to close PreparedStatement and ResultSet
      releaseConnection();
      throw new BookNotFoundException("Book not found!");
    } finally {
      this.close(null, null, ps);
      releaseConnection();
    }
}

如果没有异常发生,一切都很顺利。如果发生异常,在releaseConnection()方法之后的catch块中,抛出新的BookNotFoundException(“找不到书!”)挂起!!如果我评论releaseConnection()方法然后它正常抛出?

4 个答案:

答案 0 :(得分:5)

releaseConnection();在你的终极和你的捕获中。我不认为你想要它在你的阻挡块中。

答案 1 :(得分:1)

您正在释放连接两次。即使finally块运行,catch块也将始终运行。我的猜测是它正在执行throw,然后运行finally块,它会尝试第二次释放连接。我不确定你是如何实现releaseConnection()的,但是如果在已经释放连接时阻塞,那么这将解释问题。

我认为如果您只是从catch块移除closereleaseConnection,它应该可以正常工作。

答案 2 :(得分:1)

你要发布两次。最后,在异常情况下看起来像这样:

ps = con.prepareStatement(query);      
ps.setInt(1, bookID);      
ps.executeUpdate();
// catch
this.close(null, null, ps);
releaseConnection();     
// finally
this.close(null, null, ps);      
releaseConnection(); 
// exception flow
throw new BookNotFoundException("Book not found!");

这可能不是你想要的。

你可以删除捕获中的关闭/释放内容并离开投掷,它应该可以工作。

答案 3 :(得分:0)

抛出异常时,releaseConnection()方法被调用两次;一次在异常处理程序中,一次在最后一次。

尝试以下方法的变体:

 public void removeItem(int itemID) throws ItemNotFound
    {
        PreparedStatement ps = null;
        String query = "DELETE * FROM Student.Book WHERE id = ?";
        getConnection();
        try
        {
            ps = con.prepareStatement(query);
            ps.setInt(1, bookID);
            ps.executeUpdate();
        }
        catch (SQLException sqle)
        {
            this.close(null, null, ps); // method to close PreparedStatement and
                                                                    // ResultSet
            releaseConnection();
            throw new BookNotFoundException("Book not found!");
        }
        finally
        {
            if (isOpen())
            {
                this.close(null, null, ps);
                releaseConnection();
            }
        }
    }