try-with-resources JDBC Pool Timeout: Pool empty. чтож так
Всем привет. Написал я слой DAO JDBC, так криво как может написать эго новичок. Узнал я про try-with-resources и подумал использовать его. Очень сократил код. И тесты проходили. Но когда переписал весь слой, запустил тесты, и все пипец.
org.apache.tomcat.jdbc.pool.PoolExhaustedException: [main] Timeout: Pool empty. Unable to fetch a connection in 10 seconds, none available[size:30; busy:30; idle:0; lastwait:10000].
Вылетает после некоторого количество успешных тестов. Первая мысль, что try-with-resources не отдает в пул соединение. Но не пойму почему. По гуглу нашел подобные вопросы, но языковой барьер или усталость не дает понять, что такое случилось у меня )) ткните носом плиз.
Вот пример кода:
public Person takeBy(Integer id) throws SQLException {
Person person = null;
try (PreparedStatement statement = dataSource.getConnection().prepareStatement("select * from persons where id=?")) {
statement.setInt(1, id);
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
person = new Person(id, rs.getString("name"));
}
}
}
if (person == null) {
throw new SQLException("Person not found.");
}
return person;
}
Настройки пула:
private static DataSource getDataSourceReal() {
PoolProperties p = new PoolProperties();
p.setUrl("jdbc:mysql://127.0.0.1:8809/base?serverTimezone=Europe/Moscow");
p.setDriverClassName("com.mysql.jdbc.Driver");
p.setUsername("name");
p.setPassword("12345678");
p.setJmxEnabled(true);
p.setTestWhileIdle(false);
p.setTestOnBorrow(true);
p.setValidationQuery("SELECT 1");
p.setTestOnReturn(false);
p.setValidationInterval(30000);
p.setTimeBetweenEvictionRunsMillis(30000);
p.setMaxActive(30);
p.setInitialSize(10);
p.setMaxWait(10000);
p.setRemoveAbandonedTimeout(60);
p.setMinEvictableIdleTimeMillis(30000);
p.setMinIdle(5);
p.setMaxIdle(30);
p.setLogAbandoned(true);
p.setRemoveAbandoned(true);
p.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" +
"org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
DataSource datasource = new DataSource();
datasource.setPoolProperties(p);
return datasource;
}
Ответы (1 шт):
Первая мысль, что try-with-resources не отдает в пул соединение.
Истина где-то рядом.
У тебя
try (PreparedStatement statement = dataSource.getConnection().prepareStatement("select * from persons where id=?"))
{
//...
}
А должно быть
try(Connection con=dataSource.getConnection()){
try (PreparedStatement statement = con.prepareStatement("select * from persons where id=?"))
{
//...
}
}
Можно то же, но в один try-with-resource
try(Connection con=dataSource.getConnection(); PreparedStatement statement = con.prepareStatement("select * from persons where id=?")){
//...
}
Иными словами, ты закрывал PreparedStatement, но не закрывал Connection.