I have a question about the DriverManagerDataSource
in Spring.
Our microservice uses Spring Boot and Hibernate to connect to Druid Database. We use DriverManagerDataSource
to create our dataSource
instance. From the documentation of DriverManagerDataSource
, we know that it does not have a proper connection pool implementation.
However, when we tested the microservice, we can see 10 established TCP connections when we increased the query load to 10 concurrent virtual users, and those 10 connections remained established even after the queries completed. They only reduced to 1 connection after we initiated a new query with only 1 concurrent virtual user.
The above symptom indicates that there is indeed a connection pool established. I am pretty confused at this point: where is this pool coming from?
I tried the test mentioned here, but I got
Datasource = org.springframework.jdbc.datasource.DriverManagerDataSource@xxxx;
(pls ignore the xxxx). The following is a partial pint out of the microservice's startup that shows Tomcat started:
[30m2024-03-12 10:03:27,567[0;39m [34mINFO [0;39m [[34mmain[0;39m] [33morg.apache.juli.logging.DirectJDKLog[0;39m [,] - Starting service [Tomcat]`
[30m2024-03-12 10:03:27,568[0;39m [34mINFO [0;39m [[34mmain[0;39m] [33morg.apache.juli.logging.DirectJDKLog[0;39m [,] - Starting Servlet engine: [Apache Tomcat/9.0.86];
I am not sure if Tomcat JDBC's connection pool automatically kicked in?
org.springframework.jdbc.datasource.DriverManagerDataSource
is not a connection pool. It is a simple implementation of javax.sql.DataSource
which was autowired to the spring boot application.
Simple implementation of the standard JDBC DataSource interface, configuring the plain old JDBC
DriverManager
via bean properties, and returning a newConnection
from every getConnection call.NOTE: This class is not an actual connection pool; it does not actually pool
Connection
s. It just serves as simple replacement for a full-blown connection pool, implementing the same standard interface, but creating newConnection
s on every call.Useful for test or standalone environments outside a Jakarta EE container, either as a
DataSource
bean in a correspondingApplicationContext
or in conjunction with a simple JNDI environment. Pool-assumingConnection.close()
calls will simply close theConnection
, so anyDataSource
-aware persistence code should work.This
DriverManagerDataSource
class was originally designed alongside Apache Commons DBCP and C3P0, featuring bean-styleBasicDataSource/ComboPooledDataSource
classes with configuration properties for local resource setups. For a modern JDBC connection pool, consider HikariCP instead, exposing a correspondingHikariDataSource
instance to the application.
If you use Hibernate, you should read
1.1. Connecting Hibernate connects to databases on behalf of your application. It can connect through a variety of mechanisms, including:
Stand-alone built-in connection pool
javax.sql.DataSource
Connection pools, including support for two different third-party opensource JDBC connection pools:
c3p0
proxool
Application-supplied JDBC connections. This is not a recommended approach and exists for legacy reasons
Note: The built-in connection pool is not intended for production environments.
Hibernate obtains JDBC connections as needed though the
ConnectionProvider
interface which is a service contract. Applications may also supply their ownConnectionProvider
implementation to define a custom approach for supplying connections to Hibernate (from a different connection pool implementation, for example).Hibernate's own connection pooling algorithm is however quite rudimentary. It is intended to help you get started and is not intended for use in a production system or even for performance testing. You should use a third party pool for best performance and stability. Just replace the
hibernate.connection.pool_size
property with connection pool specific settings. This will turn off Hibernate's internal pool.
If you are not configured data sources then Hibernate will use
hibernate.connection.provider_class = org.hibernate.connection.DriverManagerConnectionProvider
This connection provider has in-built rudimentary connection pool for which you can set a
hibernate.connection.pool_size
, but it is used only for development purposes. Never use it in the production environment.
In your hibernate configuration implicitly used
DriverManagerConfigurationProvider
. This provider used by default unless you configured it with propertyconnection.provider_class
.This provider also implements a very rudimentary connection pool.
What it means "rudimentary connection pool". If you run your application you can see in the logs
[DriverManagerConnectionProvider] >Using Hibernate built-in connection pool (not for production use!) [DriverManagerConnectionProvider] >Hibernate connection pool size: 20
You can also set this value via hibernate configuration property
connection.pool_size
. But it doesn't limit you to the maximum opened connections count. You can open as many as you need connections while pool is empty. The provider will keep them open as it returns connections to pool oncloseConnection
unless the current pool size not exceeds the value in the propertyconnection.pool_size
. Once current pool size is not empty you cannot open any new connection because the connection provider returns connection from the pool.