i have a Java Servlet and i want to use connection pooling together with jdbc (Database: mysql).
So here is what i'm doing:
(This class is public final class DBConnector)
private static final HikariDataSource dataSource = new HikariDataSource();
private static final HikariDataSource dataSource2 = new HikariDataSource();
private static final HikariDataSource dataSource3 = new HikariDataSource();
static {
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/contentdb");
dataSource.setUsername("root2");
dataSource.setPassword("password");
dataSource.setMaximumPoolSize(400);
dataSource.setMinimumIdle(5);
dataSource.setLeakDetectionThreshold(15000);
dataSource.setConnectionTestQuery("SELECT 1");
dataSource.setConnectionTimeout(1000);
dataSource2.setDriverClassName("com.mysql.jdbc.Driver");
dataSource2.setJdbcUrl("jdbc:mysql://localhost:3306/userdb");
dataSource2.setUsername("root");
dataSource2.setPassword("password");
dataSource2.setMaximumPoolSize(300);
dataSource2.setMinimumIdle(5);
dataSource2.setLeakDetectionThreshold(15000);
dataSource2.setConnectionTestQuery("SELECT 1");
dataSource2.setConnectionTimeout(1000);
dataSource3.setDriverClassName("com.mysql.jdbc.Driver");
dataSource3.setJdbcUrl("jdbc:mysql://localhost:3306/analysedb");
dataSource3.setUsername("root2");
dataSource3.setPassword("password");
dataSource3.setMaximumPoolSize(200);
dataSource3.setMinimumIdle(5);
dataSource3.setLeakDetectionThreshold(15000);
dataSource3.setConnectionTestQuery("SELECT 1");
dataSource3.setConnectionTimeout(1000);
}
private DBConnector() {
//
}
public static Connection getConnection(int dataBase) throws SQLException {
if (dataBase == 0) {
return dataSource.getConnection();
} else if (dataBase == 1) {
return dataSource2.getConnection();
} else {
return dataSource3.getConnection();
}
}
And when i want to call it:
Connection con = null;
PreparedStatement query = null;
ResultSet result = null;
try {
con = DBConnector.getConnection(0);
}catch(SQLException ex){
}finally{
if (result != null) {
try {
result.close();
} catch (SQLException logOrIgnore) {
}
}
if (query != null) {
try {
query.close();
} catch (SQLException logOrIgnore) {
}
}
if (con != null) {
try {
con.close();
} catch (SQLException logOrIgnore) {
}
}
}
But when i click through my app, after a while it starts hanging and i get these errors:
java.sql.SQLException: Timeout after 1001ms of waiting for a connection.
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:208)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:108)
at main.java.db.DBConnector.getConnection(DBConnector.java:60)
at main.java.ressources.SingleItemData.getVotes(SingleItemData.java:1088)
at main.java.item.methods.GET.content.GetStreamContent.getStreamContent(GetStreamContent.java:126)
at main.java.RestService.doGet(RestService.java:254)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
I set mysql max_conncetions to 1000. The "SHOW PROCESSLIST" query shows me a lot of sleeping processes. Are these the idle ones?
I'm really kind of stuck here. Don't know which setting is causing that issue. So my question is - what causes this error? What am I doing wrong? Any help appreciated.
EDIT: Setup Mysql (localhost):
[mysqld]
user=mysql
port=3306
socket =/Applications/XAMPP/xamppfiles/var/mysql/mysql.sock
key_buffer=16M
max_allowed_packet=1M
table_open_cache=64
sort_buffer_size=512K
net_buffer_length=8K
read_buffer_size=256K
read_rnd_buffer_size=512K
myisam_sort_buffer_size=8M
max_connections = 1000
wait_timeout = 28800
interactive_timeout = 28800
HikariCP: HikariCP-java6-2.2.5.jar
MySQL Connector: mysql-connector-java-5.1.25-bin.jar
Summary. "HikariCP is solid high-performance JDBC connection pool. A connection pool is a cache of database connections maintained so that the connections can be reused when future requests to the database are required. Connection pools may significantly reduce the overall resource usage." - You can find out more here.
spring.datasource.hikari.connection-timeout=60000. Controls the maximum number of milliseconds that you will wait for setting up a connection from the pool.
Since fewer bytes are generated than the JDK Proxy, negating a lot of unnecessary byte-code, thus making it faster in execution ) Optimizations of Proxy and Interceptor: Hikari library has reduce a lot of code, e.g HikariCP's Statement proxy has only 100 lines of code.
You don't need to call DataSource's close() for every connection: Shutdown the DataSource and its associated pool. Thank you very much for your explanation. So, it's okay to call close() only during the application termination and not after every Connection is closed?
Couple of things. First, What version of HikariCP, Java, and the MySQL driver?
Second, 400 connections in one pool? Way too many! Start with 10 to 20, in each pool. You'll be surprised that you can handle a few thousand transactions per second.
Third, this is the second question in the FAQ. Read the answer and the link. You need to set maxLifetime
to something shorter (by 1 minute) than your MySQL native timeout.
Lastly, turn on DEBUG logging, HikariCP is not noisy. Every 30 seconds, the housekeeping thread runs and logs pool statistics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With