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 you can take the transition into another legal state. For example, you can make the transition from the InFreePool 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 DataSource or ConnectionFactory object.
markedStale Connection is marked as stale, typically in response to a FatalErrorNotification.
noOtherReferences There is only one connection handle to the ManagedConnection, and the Transaction Service is not holding a reference to the ManagedConnection.
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 was 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.

DoesNotExist

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.

InFreePool

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.

InUse

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

  InUse > InUse:
  getConnection AND
  ShareableConnectionAvailable

This transition states that if an application requests a shareable connection (getConnection) with the same sharing properties as a connection that is 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 isolationLevel 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. Because a transaction is normally associated with a single thread, you should never share connections across threads.

Note: 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 so far have covered getting a connection for application use. From this point, 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 unshareable 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, you 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 being returned to the pool. This situation happens if one of the connections in the pool is considered stale. A connection is considered stale if you 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 you can set your 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, you 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.