A connection handle is a representation of a physical connection.
To use a backend resource, such as a relational database in WebSphere® Application Server, you must
get a connection to that resource. When you call the getConnection()
method, you get a connection handle returned. The handle is not the
physical connection. The physical connection is managed by the connection
manager.
There are two significant configurations that affect how connection
handles are used and how they behave. The first is the res-sharing-scope,
which is defined by the resource-reference used to look up the DataSource
or Connection Factory. This property tells the connection manager
whether or not you can share this connection.
The second factor that affects connection handle behavior is the
usage pattern. There are essentially two usage patterns. The first
is called the get/use/close pattern. It is used within a single method
and without calling another method that might get a connection from
the same data source or connection factory. An application using this
pattern does the following:
- gets a connection
- does its work
- commits (if appropriate)
- closes the connection.
The second usage pattern is called the cached handle pattern.
This is where an application:
- gets a connection
- begins a global transaction
- does work on the connection
- commits a global transaction
- does work on the connection again
A cached handle is a connection handle that is held across transaction
and method boundaries by an application. Keep in mind the following
considerations for using cached handles:
- Cached handle support requires some additional connection handle
management across these boundaries, which can impact performance.
For example, in a JDBC application, Statements, PreparedStatements,
and ResultSets are closed implicitly after a transaction ends, but
the connection remains valid.
- You are encouraged not to cache the connection across the transaction
boundary for shareable connections; the get/use/close pattern is preferred.
- Caching of connection handles across servlet methods is limited
to JDBC and Java Message Service (JMS) resources.
Other non-relational resources, such as Customer Information Control
System (CICS®) or IMS™ objects,
currently cannot have their connection handles cached in a servlet;
you need to get, use, and close the connection handle within each
method invocation. (This limitation only applies to single-threaded
servlets because multithreaded servlets do not allow caching of connection
handles.)
- You cannot pass a cached connection handle from one instance of
a data access client to another client instance. Transferring between
client instances creates the problematic contingency of one instance
using a connection handle that is referenced by another. This relationship
can only cause problems because connection handle management code
processes tasks for each client instance separately. Hence, connection
handle transfers result in run-time scenarios that trigger exceptions.
For example:
- The application code of a client instance that receives a transferred
handle closes the handle.
- If the client instance that retains the original reference to
the handle tries to reclaim it, the application server issues an exception.
The following code segment shows the cached connection pattern.
Connection conn = ds.getConnection();
ut.begin();
conn.prepareStatement("....."); --> Connection runs in global transaction mode
...
ut.commit();
conn.prepareStatement("....."); ---> Connection still valid but runs in autoCommit(True);
...
Unshareable connections
Some
characteristics of connection handles retrieved with a res-sharing-scope
of unshareable are described in the following sections.
- The possible benefits of unshared connections
- Your application always maintains a direct link with a physical
connection (managed connection).
- The connection always has a one-to-one relationship between the
connection handle and the managed connection.
- In most cases, the connection does not close until the application
closes it.
- You can use a cached unshared connection handle across multiple
transactions.
- The connection can have a performance advantage in some cached
handle situations. Because unshared connections do not have the overhead
of moving connection handles off managed connections at the end of
the transaction, there is less overhead in using a cached unshared
connection.
- The possible drawbacks of unshared connections
- Inefficient use of your connection resources. For example, if
within a single transaction you get more than one connection (with
the same properties) using the same data source or connection factory
(same resource-ref) then you use multiple physical connections when
you use unshareable connections.
- Wasted connections. It is important not to keep the connection
handle open (that is, your application does not call the close() method)
any longer than the connection handle is needed. As long as an unshareable
connection is open, the physical connection is unavailable to any
other component, even if your application is not currently using that
connection. Unlike a shareable connection, an ushareable connection
is not closed at the end of a transaction or servlet call.
- Deadlock considerations. Depending on how your components interact
with the database within a transaction, using unshared connections
can lead to deadlock in the database. For example, within a transaction,
component A gets a connection to data source X and updates table 1,
and then calls component B. Component B gets another connection to
data source X, and updates/reads table 1 (or even worse the same row
as component A). In some circumstances, depending on the particular
database, its locking scheme, and the transaction isolation level,
a deadlock can occur.
In the same scenario, but with a shared connection,
deadlock does not occur because all the work is done on the same connection.
It is worth noting that when writing code that uses shared connections,
you use a strategy that calls for multiple work items to be performed
on the same connection, possibly within the same transaction. If you
decide to use an unshareable connection, you must set the maximum
connections property on the connection factory or data source correctly.
An exception might occur for waiting connection requests if you exceed
the maximum connections value, and unshareable connections are not
being closed before the connection wait time-out is exceeded.
Shareable connections
Some characteristics
of connection handles that are retrieved with a res-sharing-scope
of shareable are described in the following sections.
- The possible benefits of shared connections
- Within an instance of connection sharing, application components
can share a managed connection with one or more connection handles,
depending on how the handle is retrieved and which connection properties
are used.
- They can more efficiently use resources. Shareable connections
are not valid outside of their sharing boundary. For this reason,
at the end of a sharing boundary (such as a transaction) the connection
handle is no longer associated with the managed connection it was
using within the sharing boundary (this applies only when using the
cached handle pattern). The managed connection is returned to the
free connection pool for reuse. Connection resources are not held
longer than the end of the current sharing scope.
If the cached
handle pattern is used, then the next time the handle is used within
a new sharing scope, the application server run time ensures that
the handle is reassociated with a managed connection that is appropriate
for the current sharing scope, and has the same properties with which
the handle was originally retrieved. Remember that it is not appropriate
to change properties on a shareable connection. If properties are
changed, other components that share the same connection might experience
unexpected behavior. Futhermore, when using cached handles, the value
of the changed property might not be remembered across sharing scopes.
- The possible drawbacks of shared connections
- Sharing within a single component (such as an enterprise bean
and its related Java objects) is not always supported.
The current specification allows resource adapters the choice of only
allowing one active connection handle at a time.
If a resource
adapter chooses to implement this option then the following scenario
results in an invalid handle exception: A component using shareable
connections gets a connection and uses it. Without closing the connection,
the component calls a utility class (Java object)
that gets a connection handle to the same managed connection and uses
it. Because the resource adapter only supports one active handle,
the first connection handle is no longer valid. If the utility object
returns without closing its handle, the first handle is not valid
and triggers an exception at any attempt to use it.
Note: This
exception occurs only when calling a utility object (a Java object).
Not all resource
adapters have this limitation; it occurs only in certain implementations.
The WebSphere Relational Resource Adapter (RRA)
does not have this limitation. Any data source used through the RRA
does not have this limitation. If you encounter a resource adapter
with this limitation you can work around it by serializing your access
to the managed connection. If you always close your connection handle
before getting another (or close your handle before calling code that
gets another handle), and before returning from a method, you can
allow two pieces of code to share the same managed connection. You
simply cannot use the connection for both events at the same time.
- Trying to change the isolation level on a shareable JDBC-based
connection in a global transaction causes an exception. The correct
way to get connections with different transaction isolation levels
is by configuring the IBM® extended resource-reference.
- Closing connection handles for shareable connections by an application
is NOT supported and causes errors. However, you can avoid this limitation
by using the Relational Resource Adapter.
Lazy connection association optimization
The Java Platform, Enterprise Edition (Java EE) Connector (J2C) connection manager
implemented smart handle support. This technology enables allocation
of a connection handle to an application while the managed connection
associated with that connection handle is used by other applications
(assuming that the connection is not being used by the original application).
This concept is part of the Java EE
Connector Architecture (JCA) 1.5 specification. (You can find it in
the JCA 1.5 specification document in the section entitled
"Lazy
Connection Association Optimization.") Smart handle support introduces
use a method on the ConnectionManager object, the LazyAssociatableConnectionManager()
method , and a new marker interface, the DissociatableManagedConnection
class. You must configure the provider of the resource adapter to
make this functionality available in your environment. (In the case
of the RRA, WebSphere Application Server itself is
the provider.) The following code snippet shows how to include smart
handle support:
package javax.resource.spi;
import javax.resource.ResourceException;
interface LazyAssociatableConnectionManager { // application server
void associateConnection(
Object connection, ManagedConnectionFactory mcf,
ConnectionRequestInfo info) throws ResourceException;
}
interface DissociatableManagedConnection { // resource adapter
void dissociateConnections() throws ResourceException;
}
This DissociatableManagedConnection interface introduces
another state to the Connection object: inactive. A Connection can
now be active, closed, and inactive. The connection object enters
the inactive state when a corresponding ManagedConnection object is
cleaned up. The connection stays inactive until an application component
attempts to re-use it. Then the resource adapter calls back to the
connection manager to re-associate the connection with an active ManagedConnection
object.