Undantaget indikerar ett typiskt fall av applikationskod som läcker databasanslutningar. Du måste se till att du förvärvar och stäng alla (Connection
, Statement
och ResultSet
) i en try-with-resources
blockera i samma metodblock enligt det normala JDBC-formspråket.
public void create(Entity entity) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_CREATE);
) {
statement.setSomeObject(1, entity.getSomeProperty());
// ...
statement.executeUpdate();
}
}
Eller när du inte använder Java 7, i en try-finally
blockera. Stänger in dem finally
kommer att garantera att de också är stängda vid undantag.
public void create(Entity entity) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement(SQL_CREATE);
statement.setSomeObject(1, entity.getSomeProperty());
// ...
statement.executeUpdate();
} finally {
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
}
Ja, du måste fortfarande stänga anslutningar själv, även när du använder anslutningspoolning. Det är ett vanligt misstag bland nybörjare att de tror att det då automatiskt kommer att hantera stängningen. Detta är inte sant . Anslutningspoolen returnerar nämligen en lindad anslutning som gör ungefär följande i close():
public void close() throws SQLException {
if (this.connection is still eligible for reuse) {
do not close this.connection, but just return it to pool for reuse;
} else {
actually invoke this.connection.close();
}
}
Om du inte stänger dem skulle anslutningen inte släppas tillbaka till poolen för återanvändning och därför kommer den att få en ny om och om igen tills DB tar slut på anslutningar vilket kommer att få din applikation att krascha.
Se även:
- Hur ofta ska Connection, Statement och ResultSet stängas i JDBC?
- Är det säkert att använda en statisk java.sql.Connection-instans i ett flertrådat system?
- Stänga JDBC-anslutningar i pool