Connection Pooling : Optimizing Database Access in Java Spring Boot.
Before going to connection polling, it is important to know what is a database connection?
When your Java Spring Boot application interacts with a database, it needs to establish a connection to communicate with the database. A connection is a network communication link that allows the application to send SQL queries to the database and retrieve results.
Typical Database Connection
In a simple setup.
@Override
public List<Users> listOfUsers() {
Connection con = null;
PreparedStatement ps = null;
String sql = null;
ResultSet rs = null;
Users jm = new Users();
List<Users> li = new ArrayList<Users>();
try{
con = dataSource.getConnection(); //start the connection
sql = "select id,name,email from users"; //write the query
ps = con.prepareStatement(sql); //prepare the statement
rs = ps.executeQuery(); //execute the query and get result set
while(rs.next()){
us = new Users(
rs.getInt("id"),
rs.getString("name"),
rs.getString("email")
);
li.add(us);
}
ps.close(); //close the prepare statement
rs.close(); //close the record set
}
catch (SQLException e){
e.printStackTrace();
}
finally {
if(con != null){
try{
con.close(); //close the connection
}
catch (SQLException e){
e.printStackTrace();
}
}
}
return li;
}
This process is repeated every time the application needs to interact with the database. While this sounds straightforward, there’s a significant problem. Creating and closing database connections is expensive.
Problems with Typical Connections
Now let us see what is connection polling and how it solves the problem?
Connection pooling is a technique that solves the problem of repeatedly opening and closing database connections by reusing connections. Instead of creating a new connection for each database request, a pool of pre-established connections is maintained. When the application needs to access the database, it borrows a connection from the pool, uses it, and then returns it back to the pool rather than closing it.
How Connection Pooling Works?
How It Differs from a Typical Connection?
Connection Pooling in Spring Boot
In Spring Boot, connection pooling is usually managed by third-party libraries like HikariCP, which is the default connection pool provider. Here’s how Spring Boot manages connection pooling behind the scenes.
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=Pratyushraj@1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.max-lifetime=1800000
In this above code.
But wait a minute, how is it actually works, does it make 10 connection at a given point of time or 5?
When you configure a connection pool (like with HikariCP in Spring Boot), the number of predefined connections (like 10 in the above case) doesn't all get established immediately when you run the application. Instead, there are two key settings you should be aware of
How It Works
领英推荐
Let's say you configure the pool with these values
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
But if my application doesn't need continuous data updates then why should I use it when it costs me 5 connections at any given point of time?
If your application doesn’t need constant access to the database and only interacts with it occasionally, you might wonder why connection pooling (with even 5 idle connections) is necessary. Let's break it down and address why it's usually worth it, and when it might not be.
Why Use Connection Pooling, Even for Occasional Data Access?
Connection Creation is Expensive
-> Opening a database connection involves several steps: network setup, authentication, and resource allocation. These steps take time and resources.
-> Even if your app doesn't access the database frequently, the first access would require creating a connection from scratch if you don't use pooling. Pooling ensures that a connection is readily available when needed, avoiding this delay.
Pooling Minimizes Latency
-> When an app occasionally needs to access the database, the time to establish a connection (especially in high-latency environments) can slow down the user experience. By keeping a few connections open, you avoid delays when users request data.
-> Even with 5 idle connections, the pool can quickly serve any requests without waiting for a new connection to be made.
Managing Traffic Spikes
-> Even if your application doesn't constantly query the database, it's likely that at certain points (such as specific times of the day or during peak usage), multiple requests may come in at once.
-> Connection pooling helps handle these spikes by ensuring that a few connections are available. Otherwise, you'd face performance degradation while multiple connections are being created at once.
Cost of Idle Connections is Low
-> Modern connection pooling libraries like HikariCP are highly optimized. They efficiently manage idle connections, consuming minimal resources.
-> The cost of keeping 5 idle connections open is generally low compared to the overhead of creating connections repeatedly.
-> Database servers are also designed to handle a large number of connections without performance degradation, so having a few idle connections doesn't usually strain the server.
When to Consider Lowering or Disabling Connection Pooling
There are situations where connection pooling might not be necessary or where you can configure it to be more efficient.
Infrequent Database Access
-> If your application only accesses the database very infrequently, or only during certain scheduled tasks, you can reduce the number of idle connections.
-> For example, you can set minimum-idle=1 or even minimum-idle=0 if you really don’t need connections to be constantly open.
Single-Threaded or Small Applications
-> If you have a small app with only one or two users, or it's a single-threaded app, connection pooling might not provide significant benefits. In such cases, you could minimize the pool size to reduce resource consumption
Optimizing for Low Traffic
-> In low-traffic environments, you could configure the pool to be smaller and still get the benefits of pooling without keeping too many connections open.
spring.datasource.hikari.maximum-pool-size=5
spring.datasource.hikari.minimum-idle=1
spring.datasource.hikari.idle-timeout=10000 # 10 seconds
-> This setup would ensure that only 1 connection remains idle, and if it’s not used within 10 seconds, it will be closed. When the app needs a connection again, it will create one.
Ultimately, it's a balance between performance and resource optimization based on your application's specific needs.