与 hikari CP 的连接泄漏
connection leakage with hikari CP
我有 sql 的 jdbs 模板用于 sql 语句,并使用 hikari 连接池,经过几次调用
我例外,我使用了 try-with-resources,我的错误在哪里?(Servlet Container -Tomcat)
public class SimpleJdbcTemplate {
private Connection connection;
private DataSource dataSource;
private ResultSet resultSet;
PreparedStatement preparedStatement;
public SimpleJdbcTemplate(Connection connection) {
this.connection = connection;
}
//private DataSourse datasource - из hikariconnectionpool
public SimpleJdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) {
try (PreparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql)){
resultSet = null;
List<T> result = new ArrayList<>();
int position = 1;
for (Object arg : args) {
preparedStatement.setObject(position, arg);
position++;
}
if (sql.contains("UPDATE") || sql.contains("update") ||sql.toLowerCase().contains("delete")||sql.toLowerCase().contains("insert")) {
preparedStatement.executeUpdate();
} else{
resultSet = preparedStatement.executeQuery();
if (resultSet == null) {
throw new SQLException("No resultsSet");
}
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
}
log.info(result.toString());
return result;
} catch (SQLException e) {
throw new IllegalStateException(e);
日志:
24-Oct-2020 13:46:16.633 SEVERE [http-nio-8080-exec-3] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [servlets.view.MessendjerViewServlet] in context with path [/LabWork_war] threw exception
java.lang.IllegalStateException: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30014ms.
at repository.utill.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:52)
at repository.jdbc.UserRepositoryImpl.findUserByUUID(UserRepositoryImpl.java:84)
at service.UserService.findUser(UserService.java:71)
at servlets.filter.AuthFilter.doFilter(AuthFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30014ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:695)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:197)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:162)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)
at repository.utill.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:27)
... 22 more
好吧,我犯了个错误,这条线不能正常工作(try-with-resources)
(reparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql))
我想当我尝试关闭连接时,它从数据源 (dataSource.getConnection()) 获取了一个随机连接,所以,我的连接总是打开的,我将代码重新格式化为这个
public class SimpleJdbcTemplate {
DataSource dataSource;
//private DataSourse datasource - из hikariconnectionpool
public SimpleJdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) { //TODO repair connection leak
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement(sql);
resultSet = null;
List<T> result = new ArrayList<>();
int position = 1;
for (Object arg : args) {
preparedStatement.setObject(position, arg);
position++;
}
if (sql.contains("UPDATE") || sql.contains("update") || sql.toLowerCase().contains("delete") || sql.toLowerCase().contains("insert")) {
preparedStatement.executeUpdate();
} else {
resultSet = preparedStatement.executeQuery();
if (resultSet == null) {
throw new SQLException("No resultsSet");
}
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
}
log.info(result.toString());
return result;
} catch (SQLException e) {
throw new IllegalStateException(e);
} finally {
try {
if (resultSet != null) {
resultSet.close();
log.info("resultes finaly closed? - {}", resultSet.isClosed());
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
if (preparedStatement != null) {
try {
preparedStatement.close();
preparedStatement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
try {
if (connection != null) {
connection.close();
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
一切正常
我有 sql 的 jdbs 模板用于 sql 语句,并使用 hikari 连接池,经过几次调用 我例外,我使用了 try-with-resources,我的错误在哪里?(Servlet Container -Tomcat)
public class SimpleJdbcTemplate {
private Connection connection;
private DataSource dataSource;
private ResultSet resultSet;
PreparedStatement preparedStatement;
public SimpleJdbcTemplate(Connection connection) {
this.connection = connection;
}
//private DataSourse datasource - из hikariconnectionpool
public SimpleJdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) {
try (PreparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql)){
resultSet = null;
List<T> result = new ArrayList<>();
int position = 1;
for (Object arg : args) {
preparedStatement.setObject(position, arg);
position++;
}
if (sql.contains("UPDATE") || sql.contains("update") ||sql.toLowerCase().contains("delete")||sql.toLowerCase().contains("insert")) {
preparedStatement.executeUpdate();
} else{
resultSet = preparedStatement.executeQuery();
if (resultSet == null) {
throw new SQLException("No resultsSet");
}
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
}
log.info(result.toString());
return result;
} catch (SQLException e) {
throw new IllegalStateException(e);
日志:
24-Oct-2020 13:46:16.633 SEVERE [http-nio-8080-exec-3] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [servlets.view.MessendjerViewServlet] in context with path [/LabWork_war] threw exception java.lang.IllegalStateException: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30014ms. at repository.utill.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:52) at repository.jdbc.UserRepositoryImpl.findUserByUUID(UserRepositoryImpl.java:84) at service.UserService.findUser(UserService.java:71) at servlets.filter.AuthFilter.doFilter(AuthFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:832) Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30014ms. at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:695) at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:197) at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:162) at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100) at repository.utill.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:27) ... 22 more
好吧,我犯了个错误,这条线不能正常工作(try-with-resources) (reparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql)) 我想当我尝试关闭连接时,它从数据源 (dataSource.getConnection()) 获取了一个随机连接,所以,我的连接总是打开的,我将代码重新格式化为这个
public class SimpleJdbcTemplate {
DataSource dataSource;
//private DataSourse datasource - из hikariconnectionpool
public SimpleJdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) { //TODO repair connection leak
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement(sql);
resultSet = null;
List<T> result = new ArrayList<>();
int position = 1;
for (Object arg : args) {
preparedStatement.setObject(position, arg);
position++;
}
if (sql.contains("UPDATE") || sql.contains("update") || sql.toLowerCase().contains("delete") || sql.toLowerCase().contains("insert")) {
preparedStatement.executeUpdate();
} else {
resultSet = preparedStatement.executeQuery();
if (resultSet == null) {
throw new SQLException("No resultsSet");
}
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
}
log.info(result.toString());
return result;
} catch (SQLException e) {
throw new IllegalStateException(e);
} finally {
try {
if (resultSet != null) {
resultSet.close();
log.info("resultes finaly closed? - {}", resultSet.isClosed());
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
if (preparedStatement != null) {
try {
preparedStatement.close();
preparedStatement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
try {
if (connection != null) {
connection.close();
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
一切正常