+

Search Tips   |   Advanced Search

Connection life cycle

A ManagedConnection object is always in one of three states: DoesNotExist, InFreePool, or InUse.

Before a connection is created, it must be in the DoesNotExist state. After a connection is created, it can be in either the InUse or the InFreePool state, depending on whether it is allocated to an application.

Between these three states are transitions. These transitions are controlled by guarding conditions. A guarding condition is one in which true indicates when we can take the transition into another legal state. For example, we can make the transition from the InFreePool state to InUse state only if:

This transition description follows:

InFreePool > InUse:
getConnection AND
freeConnectionAvailable AND
NOT(shareableConnectionAvailable)
Here is a list of guarding conditions and descriptions.

Condition Description
ageTimeoutExpired Connection is older then its ageTimeout value.
close Application calls close method on the Connection object.
fatalErrorNotification A connection has just experienced a fatal error.
freeConnectionAvailable A connection with matching properties is available in the free pool.
getConnection Application calls getConnection method on a data source or connection factory object.
markedStale Connection is marked as stale, typically in response to a fatal error notification.
noOtherReferences There is only one connection handle to the managed connection, and the Transaction Service is not holding a reference to the managed connection.
noTx No transaction is in force.
poolSizeGTMin Connection pool size is greater than the minimum pool size (minimum number of connections)
poolSizeLTMax Pool size is less than the maximum pool size (maximum number of connections)
shareableConnectionAvailable The getConnection() request is for a shareable connection, and one with matching properties is in use and available to share.
TxEnds The transaction has ended.
unshareableConnectionRequest The getConnection() request is for an unshareable connection.
unusedTimeoutExpired Connection is in the free pool and not in use past its unused timeout value.


Getting connections

The first set of transitions covered are those in which the application requests a connection from either a data source or a connection factory. In some of these scenarios, a new connection to the database results. In others, the connection might be retrieved from the connection pool or shared with another request for a connection.

Every connection begins its life cycle in the DoesNotExist state. When an application server starts, the connection pool does not exist. Therefore, there are no connections. The first connection is not created until an application requests its first connection. Additional connections are created as needed, according to the guarding condition.

getConnection AND
NOT(freeConnectionAvailable) AND
poolSizeLTMax AND
(NOT(shareableConnectionAvailable) OR
unshareableConnectionRequest)

This transition specifies that a connection object is not created unless the following conditions occur:

All connections begin in the DoesNotExist state and are only created when the application requests a connection. The pool grows from 0 to the maximum number of connections as applications request new connections. The pool is not created with the minimum number of connections when the server starts.

If the request is for a sharable connection and a connection with the same sharing properties is already in use by the application, the connection is shared by two or more requests for a connection. In this case, a new connection is not created. For users of the JDBC API these sharing properties are most often userid/password and transaction context; for users of the Resource Adapter Common Client Interface (CCI) they are typically ConnectionSpec, Subject, and transaction context.

The transition from the InFreePool state to the InUse state is the most common transition when the application requests a connection from the pool.

InFreePool>InUse:
getConnection AND
freeConnectionAvailable AND
(unshareableConnectionRequest OR
NOT(shareableConnectionAvailable))

This transition states that a connection is placed in use from the free pool if:

Any connection request that a connection from the free pool can fulfill does not result in a new connection to the database. Therefore, if there is never more than one connection used at a time from the pool by any number of applications, the pool never grows beyond a size of one. This number can be less than the minimum number of connections specified for the pool. One way that a pool grows to the minimum number of connections is if the application has multiple concurrent requests for connections that must result in a newly created connection.

The idea of connection sharing is seen in the transition on the InUse state.

InUse>InUse:
getConnection AND
ShareableConnectionAvailable

This transition indicates that if an application requests a shareable connection (getConnection) with the same sharing properties as a connection already in use (ShareableConnectionAvailable), the existing connection is shared.

The same user (user name and password, or subject, depending on authentication choice) can share connections but only within the same transaction and only when all of the sharing properties match. For JDBC connections, these properties include the isolation level, which is configurable on the resource-reference (IBM WebSphere extension) to data source default. For a resource adapter factory connection, these properties include those specified on the ConnectionSpec object. Because a transaction is normally associated with a single thread, we should never share connections across threads.

It is possible to see the same connection on multiple threads at the same time, but this situation is an error state usually caused by an application programming error.


Returning connections

All of the transitions discussed previously involve getting a connection for application use. With that goal, the transitions result in a connection closing, and either returning to the free pool or being destroyed. Applications should explicitly close connections (note: the connection that the user gets back is really a connection handle) by calling close() on the connection object. In most cases, this action results in the following transition:
InUse>InFreePool:
(close AND
noOtherReferences AND
NoTx AND
UnshareableConnection)
OR
(ShareableConnection AND
TxEnds)

Conditions that cause the transition from the InUse state are:

When the application calls close() on a connection, it is returning the connection to the pool of free connections; it is not closing the connection to the data store. When the application calls close() on a currently shared connection, the connection is not returned to the free pool. Only after the application drops the last reference to the connection, and the transaction is over, is the connection returned to the pool. Applications using unsharable connections must take care to close connections in a timely manner. Failure to do so can starve out the connection pool, making it impossible for any application running on the server to get a connection.

When the application calls close() on a connection enlisted in a transaction, the connection is not returned to the free pool. Because the transaction manager must also hold a reference to the connection object, the connection cannot return to the free pool until the transaction ends. Once a connection is enlisted in a transaction, we cannot use it in any other transaction by any other application until after the transaction is complete.

There is a case where an application calling close() can result in the connection to the data store closing and bypassing the connection return to the pool. This situation happens if one of the connections in the pool is considered stale. A connection is considered stale if we can no longer use it to contact the data store. For example, a connection is marked stale if the data store server is shut down. When a connection is marked as stale, the entire pool is cleaned out by default because it is very likely that all of the connections are stale for the same reason (or we can set the configuration to clean just the failing connection). This cleansing includes marking all of the currently InUse connections as stale so they are destroyed upon closing. The following transition states the behavior on a call to close() when the connection is marked as stale:

InUse>DoesNotExist:
close AND
markedStale AND
NoTx AND
noOtherReferences

This transition states that if the application calls close() on the connection and the connection is marked as stale during the pool cleansing step (markedStale), the connection object closes to the data store and is not returned to the pool.

Finally, we can close connections to the data store and remove them from the pool.

This transition states that there are three cases in which a connection is removed from the free pool and destroyed.

  1. If a fatal error notification is received from the resource adapter (or data source). A fatal error notification (FatalErrorNotification) is received from the resource adaptor when something happens to the connection to make it unusable. All connections currently in the free pool are destroyed.

  2. If the connection is in the free pool for longer than the unused timeout period (UnusedTimeoutExpired) and the pool size is greater than the minimum number of connections (poolSizeGTMin), the connection is removed from the free pool and destroyed. This mechanism enables the pool to shrink back to its minimum size when the demand for connections decreases.

  3. If an age timeout is configured and a given connection is older than the timeout. This mechanism provides a way to recycle connections based on age.


Related:

  • Relational resource adapters and JCA
  • Data sources
  • Connection pooling
  • Unshareable and shareable connections
  • Connection handles