
The Payara Monthly Catch – August 2025
Welcome aboard the August 2025 issue of The Payara Monthly Catch! With summer in full swing, things may have felt […]
As part of the Payara Enterprise Support services that we deliver to customers on a daily basis, giving expert advice and clarifying how the internals of the products of the Payara Platform work is one of the most common scenarios we encounter. Here’s’ a story about the advice we gave to one of our customers regarding the behavior of JDBC Connection Pools in Payara Server.
A customer who is migrating his applications to Payara Server 5.x wanted a direct reply to this question posted on StackOverflow:
I would like to know how many database connections from my database pool are occupied during the call of the following example code.
I cannot really find the answer when looking at:
When I have a connection pool with 50 connections can I call this method 50 times without a problem, or can I call this method 25 times before the pool runs out of connections?
NOTE: I do not configure the JEE application server to use ‘Pinned-To-Thread’ or ‘associate-with-thread’ application server specific database connection pool settings.
I come as close as: how an application server may handle a connection request from the application
The customer’s question is targeted to the general Java EE body of specifications. The problem is that none of its specifications and APIs define the behavior that application servers should apply in the case of connection pool resources. The answer that was given to the customer was in the context of how connection pools work in Payara Server.
Before answering this question we have to make the distinction between logical connections and physical connections:
DriverManager
or DataSource
classes to connect directly to the database using explicit connection parameters (username, password, server name, URL, etc). Physical connection objects are destroyed when garbage collected after they are explicitly closed. When developing Java EE applications, physical connections are discouraged.DataSource.getConnection
), the pool simply hands an available connection (or will create a new one if needed). When an application is done with the connection (by explicitly closing it or the underlying transaction is completed), the connection is simply returned to the pool. It will be destroyed (and garbage collected) only then the pool manager decides it so.In the code sample, two connections are acquired from the pool and when the method is finished and the transaction is successfully committed (or a rollback occurs), the connections will be released and returned to the pool.
However, under a non-transactional context (for example, when using TransactionAttributeType.NOT_SUPPORTED
or TransactionAttributeType.NEVER
) connections will be released either when they are explicitly closed by the application or when the current business method finishes (on a Stateless
EJB bean this happens when the invoker finishes its execution on the caller’s side). I tested this intensively by running load tests again using this code sample and on multiple times, connections were released immediately after the invoker call finished. Only on rare cases, connections were released when explicitly closing them.
Will the connections remain occupied until the transaction is completed? Or are they freed to the database connection pool and JEE handles the commit in an invisible way?
YES, connections will remain acquired when they have been requested by any application component and they will be released when explicitly closed or the underlying transaction completes (committed successfully, rollback, or times out). The connection pool will never handle the completion of any underlying JTA transaction, but it will commit the database transaction as instructed by the transaction manager when the transaction is signaled for commit.
When I have a connection pool with 50 connections can I call this method 50 times without a problem, or can I call this method 25 times before the pool runs out of connections?
Connection pools behave by restricting the number of connections given to applications. This behaviour is controlled by the following pool parameters/properties:
32.
300s.
2
60000ms=60s.
Taking all of this into account, the answer is: It depends on the parameters of the pool. Using the default parameters, launching 50 concurrent calls to the same method will work without problems:
8
connections in the pool, so it will max out to 32
after the 32nd call to the method. New connections will be created on the 9th call onwards.60s.
32
connections will be released to the pool again and they will be immediately acquired by the remaining 18 method calls. The remaining 32 first calls then will start the waiting period for 30s.
18
connections will be released to the pool, and these method calls will enter their sleep period.32
connections will be acquired by them and their SQL updates will be issued. Assuming an immediate response to the database, these connections will be released immediately.8
connections.So for the span of this scenario (10 minutes), 100 connections were acquired, 100 connections released, 40 created and 32 destroyed. The following Grafana graphs show these metrics in a timeline:
NOTE: I do not configure the JEE application server to use ‘Pinned-To-Thread’ or ‘associate-with-thread’ application server specific database connection pool settings.
The Associate With Thread option does not affect the behaviour of this scenario since the sample code will release the connections to the pool by explicitly closing them.
I come as close as how an application server may handle a connection request from the application
getConnection
method.Connection
object reference to the application.XAResource.end
to disassociate the transaction from the XAResource
.XAResource.prepare
to inform the resource manager to prepare the transaction work for commit.XAResource.commit
to commit the transaction.This process is “mostly” accurate. However, JDBC resources (connections) are not necessarily delisted when the connection is closed. They can either remain enlisted in the same transaction when the connection is reused in the span of the original JTA transaction.
So in summary, JDBC connection pools will behave accordingly based on the parameters used to configure its size and idle behavior. We encourage users of Payara Server that want to better understand how connection pools work to experiment with them after reading the concepts that I referenced.
Need support for Payara Platform in production? Learn more about Payara Enterprise:
{{cta(‘2701aff7-585c-4b76-b77f-32ee1b11c47a’)}}
Share:
Welcome aboard the August 2025 issue of The Payara Monthly Catch! With summer in full swing, things may have felt […]
Your Round-Up of the Latest Java & Jakarta EE News. Welcome aboard the July issue of The Monthly Catch. As […]
When the SIFMA Foundation needed to modernize its aging financial education platform used by thousands of students, it turned […]
Interesting!
I’d like to include the Grafana graph of the screenshot in our monitoring. What JMX-values do I have to look for?