The Tomcat JDBC Connection Pool

Table of Contents


The JDBC Connection Pool org.apache.tomcat.jdbc.pool is a replacement or an alternative to the Apache Commons DBCP connection pool.

So why do we need a new connection pool?

Here are a few of the reasons:

  1. Commons DBCP 1.x is single threaded. In order to be thread safe Commons locks the entire pool for short periods during both object allocation and object return. Note that this does not apply to Commons DBCP 2.x.
  2. Commons DBCP 1.x can be slow. As the number of logical CPUs grows and the number of concurrent threads attempting to borrow or return objects increases, the performance suffers. For highly concurrent systems the impact can be significant. Note that this does not apply to Commons DBCP 2.x.
  3. Commons DBCP is over 60 classes. tomcat-jdbc-pool core is 8 classes, hence modifications for future requirement will require much less changes. This is all you need to run the connection pool itself, the rest is gravy.
  4. Commons DBCP uses static interfaces. This means you have to use the right version for a given JRE version or you may see NoSuchMethodException exceptions.
  5. It's not worth rewriting over 60 classes, when a connection pool can be accomplished with a much simpler implementation.
  6. Tomcat jdbc pool implements the ability retrieve a connection asynchronously, without adding additional threads to the library itself.
  7. Tomcat jdbc pool is a Tomcat module, it depends on Tomcat JULI, a simplified logging framework used in Tomcat.
  8. Retrieve the underlying connection using the javax.sql.PooledConnection interface.
  9. Starvation proof. If a pool is empty, and threads are waiting for a connection, when a connection is returned, the pool will awake the correct thread waiting. Most pools will simply starve.

Features added over other connection pool implementations

  1. Support for highly concurrent environments and multi core/cpu systems.
  2. Dynamic implementation of interface, will support java.sql and javax.sql interfaces for your runtime environment (as long as your JDBC driver does the same), even when compiled with a lower version of the JDK.
  3. Validation intervals - we don't have to validate every single time we use the connection, we can do this when we borrow or return the connection, just not more frequent than an interval we can configure.
  4. Run-Once query, a configurable query that will be run only once, when the connection to the database is established. Very useful to setup session settings, that you want to exist during the entire time the connection is established.
  5. Ability to configure custom interceptors. This allows you to write custom interceptors to enhance the functionality. You can use interceptors to gather query stats, cache session states, reconnect the connection upon failures, retry queries, cache query results, and so on. Your options are endless and the interceptors are dynamic, not tied to a JDK version of a java.sql/javax.sql interface.
  6. High performance - we will show some differences in performance later on
  7. Extremely simple, due to the very simplified implementation, the line count and source file count are very low, compare with c3p0 that has over 200 source files(last time we checked), Tomcat jdbc has a core of 8 files, the connection pool itself is about half that. As bugs may occur, they will be faster to track down, and easier to fix. Complexity reduction has been a focus from inception.
  8. Asynchronous connection retrieval - you can queue your request for a connection and receive a Future<Connection> back.
  9. Better idle connection handling. Instead of closing connections directly, it can still pool connections and sizes the idle pool with a smarter algorithm.
  10. You can decide at what moment connections are considered abandoned, is it when the pool is full, or directly at a timeout by specifying a pool usage threshold.
  11. The abandon connection timer will reset upon a statement/query activity. Allowing a connections that is in use for a long time to not timeout. This is achieved using the ResetAbandonedTimer
  12. Close connections after they have been connected for a certain time. Age based close upon return to the pool.
  13. Get JMX notifications and log entries when connections are suspected for being abandoned. This is similar to the removeAbandonedTimeout but it doesn't take any action, only reports the information. This is achieved using the suspectTimeout attribute.
  14. Connections can be retrieved from a java.sql.Driver, javax.sql.DataSource or javax.sql.XADataSource This is achieved using the dataSource and dataSourceJNDI attributes.
  15. XA connection support

How to use

Usage of the Tomcat connection pool has been made to be as simple as possible, for those of you that are familiar with commons-dbcp, the transition will be very simple. Moving from other connection pools is also fairly straight forward.

Additional features

The Tomcat connection pool offers a few additional features over what most other pools let you do:

  • initSQL - the ability to run a SQL statement exactly once, when the connection is created
  • validationInterval - in addition to running validations on connections, avoid running them too frequently.
  • jdbcInterceptors - flexible and pluggable interceptors to create any customizations around the pool, the query execution and the result set handling. More on this in the advanced section.
  • fairQueue - Set the fair flag to true to achieve thread fairness or to use asynchronous connection retrieval

Inside the Apache Tomcat Container

The Tomcat Connection pool is configured as a resource described in The Tomcat JDBC documentation With the only difference being that you have to specify the factory attribute and set the value to org.apache.tomcat.jdbc.pool.DataSourceFactory


The connection pool only has another dependency, and that is on tomcat-juli.jar. To configure the pool in a stand alone project using bean instantiation, the bean to instantiate is org.apache.tomcat.jdbc.pool.DataSource. The same attributes (documented below) as you use to configure a connection pool as a JNDI resource, are used to configure a data source as a bean.


The connection pool object exposes an MBean that can be registered. In order for the connection pool object to create the MBean, the flag jmxEnabled has to be set to true. This doesn't imply that the pool will be registered with an MBean server, merely that the MBean is created. In a container like Tomcat, Tomcat itself registers the DataSource with the MBean server, the org.apache.tomcat.jdbc.pool.DataSource object will then register the actual connection pool MBean. If you're running outside of a container, you can register the DataSource yourself under any object name you specify, and it propagates the registration to the underlying pool. To do this you would call mBeanServer.registerMBean(dataSource.getPool().getJmxPool(),objectname). Prior to this call, ensure that the pool has been created by calling dataSource.createPool().


To provide a very simple switch to and from commons-dbcp and tomcat-jdbc-pool, Most attributes are the same and have the same meaning.

JNDI Factory and Type

Attribute Description

factory is required, and the value should be org.apache.tomcat.jdbc.pool.DataSourceFactory


Type should always be javax.sql.DataSource or javax.sql.XADataSource

Depending on the type a org.apache.tomcat.jdbc.pool.DataSource or a org.apache.tomcat.jdbc.pool.XADataSource will be created.

System Properties

System properties are JVM wide, affect all pools created in the JVM

Attribute Description

(boolean) Controls classloading of dynamic classes, such as JDBC drivers, interceptors and validators. If set to false, default value, the pool will first attempt to load using the current loader (i.e. the class loader that loaded the pool classes) and if class loading fails attempt to load using the thread context loader. Set this value to true, if you wish to remain backwards compatible with Apache Tomcat 8.0.8 and earlier, and only attempt the current loader. If not set then the default value is false.

Common Attributes

These attributes are shared between commons-dbcp and tomcat-jdbc-pool, in some cases default values are different.

Attribute Description

(boolean) The default auto-commit state of connections created by this pool. If not set, default is JDBC driver default (If not set then the setAutoCommit method will not be called.)


(boolean) The default read-only state of connections created by this pool. If not set then the setReadOnly method will not be called. (Some drivers don't support read only mode, ex: Informix)


(String) The default TransactionIsolation state of connections created by this pool. One of the following: (see javadoc )

  • NONE

If not set, the method will not be called and it defaults to the JDBC driver.


(String) The default catalog of connections created by this pool.


(String) The fully qualified Java class name of the JDBC driver to be used. The driver has to be accessible from the same classloader as tomcat-jdbc.jar


(String) The connection username to be passed to our JDBC driver to establish a connection. Note that method DataSource.getConnection(username,password) by default will not use credentials passed into the method, but will use the ones configured here. See alternateUsernameAllowed property for more details.


(String) The connection password to be passed to our JDBC driver to establish a connection. Note that method DataSource.getConnection(username,password) by default will not use credentials passed into the method, but will use the ones configured here. See alternateUsernameAllowed property for more details.


(int) The maximum number of active connections that can be allocated from this pool at the same time. The default value is 100


(int) The maximum number of connections that should be kept in the pool at all times. Default value is maxActive:100 Idle connections are checked periodically (if enabled) and connections that been idle for longer than minEvictableIdleTimeMillis will be released. (also see testWhileIdle)


(int) The minimum number of established connections that should be kept in the pool at all times. The connection pool can shrink below this number if validation queries fail. Default value is derived from initialSize:10 (also see testWhileIdle)


(int)The initial number of connections that are created when the pool is started. Default value is 10


(int) The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception. Default value is 30000 (30 seconds)


(boolean) The indication of whether objects will be validated before being borrowed from the pool. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another. In order to have a more efficient validation, see validationInterval. Default value is false


(boolean) The indication of whether objects will be validated when a connection is first created. If an object fails to validate, it will be throw SQLException. Default value is false


(boolean) The indication of whether objects will be validated before being returned to the pool. The default value is false.


(boolean) The indication of whether objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool. The default value is false and this property has to be set in order for the pool cleaner/test thread is to run (also see timeBetweenEvictionRunsMillis)


(String) The SQL query that will be used to validate connections