2011-03-02 100 views
2

我正在审查大量现有代码,试图查找会导致连接池用完或抛出其他错误的未关闭连接。MySQL和JDBC连接池:未关闭的语句

在一些地方我看到连接返回到池,ResultSet被关闭,但PreparedStatement没有关闭。

在伪代码

它应该是这样的:

Connection conn = null; 
try { 
    conn = MyJdbcTemplateHolder.getNewConnectionFromPool(); 
    PreparedStatement ps = conn.prepareStatement(sql, ...); 
    ResultSet rs = st.executeQuery(); 

    // do stuff with results 

} catch(Exception e) { 
    // exception 
} finally { 
    rs.close(); 
    MyJdbcTemplateHolder.returnConnectionToPool(conn); 
    //***** Here is what's missing: st.close(); ***** 
} 

的问题是:可以公开声明的原因的问题,因为它没有明确关闭?或者正在关闭ResultSet并返回足够的连接?

很显然,我不是在谈论一个开放的声明 - 我们有100个连接池和数十个可能出现此问题的代码位置。

  • MySQL的版本是5.1
  • 我的JDBC罐子使用mysql-connector-java的5.1.11-bin.jar

回答

2

答案是肯定的,它可能会导致问题。正如这里讨论的SO:

如果你与他们所做的(或在finally块后做相反的顺序不紧密连接相关的资源

),你有风险。连接池根据它们的处理方式而有所不同,但令人担忧的是 - 至少 - 将不正确关闭的一组资源抛入池中。

在情况下,目前还不清楚(你可能已经知道这一点),资源的正确关闭是进一步讨论在这里:

注意,在即将到来的Java 7中,将有我们有所帮助:

http://www.javaspecialists.eu/archive/Issue190.html

中一种新的尝试,与资源声明是在Java中引入的,它会自动关闭try语句中引用的任何AutoCloseable资源。

+1

+1 - 是!简短的回答。按照您打开它的相反顺序关闭所有JDBC。永远,永远,永远。如果你没有做到这一点,这需要一个根深蒂固的习惯,足以解决它。 – rfeak 2011-03-02 16:34:40

+0

感谢kvista,我明白了,这就是我所害怕的......我认为这个代码会有很多工作。有没有人知道我应该期待什么样的行为,因为未公开的陈述?或者他们在封面下发生了什么? – Galz 2011-03-02 17:15:43

+0

我的个人经验是数据库没有连接,因为他们没有被清理和徘徊。池会要求新的数据库,最终数据库将不再提供。随着时间的推移,数据库最终会清理连接,但速度比他们“泄露”的速度慢。 – rfeak 2011-03-02 17:40:34