10 Labeling Connections
- What is Connection Labeling
Applications often initialize connections retrieved from a connection pool before using the connection. The initialization varies and could include simple state re-initialization that requires method calls within the application code or database operations that require round trips over the network. The cost of such initialization may be significant. Labeling connections allows an application to attach arbitrary name/value pairs to a connection. - Implementing Labeling Callbacks
A labeling callback is used to define how the connection pool selects labeled connections and allows the selected connection to be configured before returning it to an application. Applications that use the connection labeling feature must provide a callback implementation. - Creating a Labeling Callback
A labeling callback is used to define how the connection pool selects labeled connections and allows the selected connection to be configured before returning it to an application. Learn how to create a labeling callback by implementing theoracle.ucp.ConnectionLabelingCallback
interface. - Registering a Labeling Callback
A WebLogic Server data source provides theregisterConnectionLabelingCallback(ConnectionLabelingCallback callback)
method for registering labeling callbacks. Only one callback may be registered on a connection pool. - Reserving Labeled Connections
WebLogic JDBC data sources provide twogetConnection
methods that are used for reserving a labeled connection from the pool. - Checking Unmatched labels
Connections may have multiple labels, which each uniquely identify the connection based on specified criteria. Use thegetUnmatchedConnectionLabels
method to verify which connections do not match the requested label. - Removing a Connection Label
You can remove a connection label by using theremoveConnectionLabel
method. - Using Initialization and Reinitialization Costs to Select Connections
Some applications require that a connection pool be able to identify high-cost connections and avoid using those connections when the number of connections is below a certain threshold. Using that information allows a connection pool to use new physical connections to serve connection requests from different tenants without incurring reinitialization overhead on other tenant connections already in the pool. - Using Connection Labeling with Packaged Applications
WebLogic Server allows callbacks, such as connection labeling and connection initialization, in EAR or WAR files used by a packaged application.
What is Connection Labeling
Applications often initialize connections retrieved from a connection pool before using the connection. The initialization varies and could include simple state re-initialization that requires method calls within the application code or database operations that require round trips over the network. The cost of such initialization may be significant. Labeling connections allows an application to attach arbitrary name/value pairs to a connection.
The application can request a connection with the desired label from the connection pool. The connection labeling feature does not impose any meaning on user-defined keys or values; the meaning of user-defined keys and values is defined solely by the application.
Some of the examples for connection labeling include role, NLS language settings, transaction isolation levels, stored procedure calls, or any other state initialization that is expensive and necessary on the connection before work can be executed by the resource.
Connection labeling is application-driven and requires the following:
-
The
oracle.ucp.jdbc.LabelableConnection
interface is used to apply and remove connection labels, as well as retrieve labels that have been set on a connection. -
The
oracle.ucp.ConnectionLabelingCallback
interface is used to create a labeling callback that determines whether or not a connection with a requested label already exists. If no connections exist, the interface allows current connections to be configured as required. -
A
Connection Labeling Callback
, see JDBC Data Source: Configuration: Connection Pool in Oracle WebLogic Server Administration Console Online Help.
Parent topic: Labeling Connections
Implementing Labeling Callbacks
A labeling callback is used to define how the connection pool selects labeled connections and allows the selected connection to be configured before returning it to an application. Applications that use the connection labeling feature must provide a callback implementation.
A labeling callback is used when a labeled connection is requested but there are no connections in the pool that match the requested labels. The callback determines which connection requires the least amount of work in order to be re-configured to match the requested label and then allows the connection's labels to be updated before returning the connection to the application.
Note:
Connection Labeling is not supported from client applications that use RMI. See Using the WebLogic RMI Driver (Deprecated) in Developing JDBC Applications for Oracle WebLogic Server.
Parent topic: Labeling Connections
Creating a Labeling Callback
A labeling callback is used to define how the connection pool selects labeled connections and allows the selected connection to be configured before returning it to an application. Learn how to create a labeling callback by implementing the oracle.ucp.ConnectionLabelingCallback
interface.
To create a labeling callback, an application implements the oracle.ucp.ConnectionLabelingCallback
interface. One callback is created per connection pool. The interface provides two methods as shown below:
public int cost(Properties requestedLabels, Properties currentLabels);
public boolean configure(Properties requestedLabels, Connection conn);
The connection pool iterates over each connection available in the pool. For each connection, it calls the cost
method. The result of the cost
method is an integer which represents an estimate of the cost required to reconfigure the connection to the required state. The larger the value, the costlier it is to reconfigure the connection. The connection pool always returns connections with the lowest cost value. The algorithm is as follows:
-
If the cost method returns 0 for a connection, the connection is a match (note that this does not guarantee that
requestedLabels
equalscurrentLabels
). The connection pool does not call configure on the connection found and simply returns the connection. -
If the cost method returns a value that is not 0 (a negative or positive integer), then the connection pool iterates until it finds a connection with a cost value of 0 or runs out of available connections.
-
If the pool has iterated through all available connections and the lowest cost of a connection is
Integer.MAX_VALUE
(2147483647 by default), then no connection in the pool is able to satisfy the connection request. The pool creates a new connection, calls theconfigure
method on it, and then returns this new connection. If the pool has reached the maximum pool size (it cannot create a new connection), then the pool either throws an SQL exception or waits if the connection wait timeout attribute is specified. -
If the pool has iterated through all available connections and the lowest cost of a connection is less than
Integer.MAX_VALUE
, then the configure method is called on the connection and the connection is returned. If multiple connections are less thanInteger.MAX_VALUE
, the connection with the lowest cost is returned.
There is also an extended callback interface oracle.ucp.jdbc.ConnectionLabelingCallback
that has an additional getRequestedLabels()
method. getRequestedLabels
is invoked at getConnection()
time when no requested labels are provided and there is an instance registered. This occurs when the standard java.sql.Datasource
getConnection()
methods are used that do not provide the label information on the getConnection()
call.
Parent topic: Labeling Connections
Example Labeling Callback
The following code example demonstrates a simple labeling callback implementation that implements both the cost
and configure
methods. The callback is used to find a labeled connection that is initialized with a specific transaction isolation level.
Example 10-1 Labeling Callback
import oracle.ucp.jdbc.ConnectionLabelingCallback; import oracle.ucp.jdbc.LabelableConnection; import java.util.Properties; import java.util.Map; import java.util.Set; import weblogic.jdbc.extensions.WLDataSource; class MyConnectionLabelingCallback implements ConnectionLabelingCallback { public MyConnectionLabelingCallback() { } public int cost(Properties reqLabels, Properties currentLabels) { // Case 1: exact match if (reqLabels.equals(currentLabels)) { System.out.println("## Exact match found!! ##"); return 0; } // Case 2: some labels match with no unmatched labels String iso1 = (String) reqLabels.get("TRANSACTION_ISOLATION"); String iso2 = (String) currentLabels.get("TRANSACTION_ISOLATION"); boolean match = (iso1 != null && iso2 != null && iso1.equalsIgnoreCase(iso2)); Set rKeys = reqLabels.keySet(); Set cKeys = currentLabels.keySet(); if (match && rKeys.containsAll(cKeys)) { System.out.println("## Partial match found!! ##"); return 10; } // No label matches to application's preference. // Do not choose this connection. System.out.println("## No match found!! ##"); return Integer.MAX_VALUE; } public boolean configure(Properties reqLabels, Object conn) { try { String isoStr = (String) reqLabels.get("TRANSACTION_ISOLATION"); ((Connection)conn).setTransactionIsolation(Integer.valueOf(isoStr)); LabelableConnection lconn = (LabelableConnection) conn; // Find the unmatched labels on this connection Properties unmatchedLabels = lconn.getUnmatchedConnectionLabels(reqLabels); // Apply each label <key,value> in unmatchedLabels to conn for (Map.Entry<Object, Object> label : unmatchedLabels.entrySet()) { String key = (String) label.getKey(); String value = (String) label.getValue(); lconn.applyConnectionLabel(key, value); } } catch (Exception exc) { return false; } return true; } public java.util.Properties getRequestedLabels() { Properties props = new Properties(); // Set based on some application state that might be on a thread-local, http session info, etc. String value = "value"; props.put("TRANSACTION_ISOLATION", value); return props; } }
Parent topic: Creating a Labeling Callback
Registering a Labeling Callback
A WebLogic Server data source provides the registerConnectionLabelingCallback(ConnectionLabelingCallback callback)
method for registering labeling callbacks. Only one callback may be registered on a connection pool.
See, the registerConnectionLabelingCallback(ConnectionLabelingCallback callback)
method for registering labeling callbacks. The following code example demonstrates registering a labeling callback that is implemented in the MyConnectionLabelingCallback
class:
. . . import weblogic.jdbc.extensions.WLDataSource; . . . MyConnectionLabelingCallback callback = new MyConnectionLabelingCallback(); ((WLDataSource)ds).registerConnectionLabelingCallback( callback ); . . .
You can also register the callback using the WebLogic Server Administration Console, see Configure a connection labeling callback class in Oracle WebLogic Server Administration Console Online Help.
Removing a Labeling Callback
You can remove a labeling callback by using one of the following methods:
-
If you have programmatically set a callback, use the
removeConnectionLabelingCallback()
method as shown in the following example:. . . import weblogic.jdbc.extensions.WLDataSource; . . . ((WLDataSource)ds).removeConnectionLabelingCallback( callback ); . . .
-
If you have administratively configured the callback, remove the callback from the data source configuration. See Configure a connection labeling callback class in Oracle WebLogic Server Administration Console Online Help.
Note:
An application must use one of the methods to register and remove callbacks but not both. For example, if you register the callback on a connection using registerConnectionLabelingCallback(callback)
, you must use removeConnectionLabelingCallback()
to remove it.
Parent topic: Registering a Labeling Callback
Applying Connection Labels
Labels are applied on a reserved connection using the applyConnectionLabel
method from the LabelableConnection
interface. Any number of connection labels may be cumulatively applied on a reserved connection. Each time a label is applied to a connection, the supplied key/value pair is added to the existing collection of labels. Only the last applied value is retained for any given key.
Note:
A labeling callback must be registered on the connection pool before a label can be applied on a reserved connection; otherwise, labeling is ignored. See Creating a Labeling Callback.
The following example demonstrates initializing a connection with a transaction isolation level and then applying a label to the connection:
. . . String pname = "property1"; String pvalue = "value"; Connection conn = ds.getConnection(); // initialize the connection as required. conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); ((LabelableConnection) conn).applyConnectionLabel(pname, pvalue); . . .
Parent topic: Registering a Labeling Callback
Reserving Labeled Connections
WebLogic JDBC data sources provide two getConnection
methods
that are used for reserving a labeled connection from the pool.
-
Public Connection
getConnection(java.util.Properties labels)
-
Public Connection
getConnection(String user, String password, java.util.Properties labels)
The methods require that the label be passed to the getConnection
method as a Properties
object. The following example demonstrates getting a connection with the label property1 value.
. . . import weblogic.jdbc.extensions.WLDataSource; . . . String pname = "property1"; String pvalue = "value"; Properties label = new Properties(); label.setProperty(pname, pvalue); . . . Connection conn = ((WLDataSource)ds).getConnection(label); . . .
It is also possible to use the standard java.sql.Datasource getConnection()
methods. In this case, the label information is not provided on the getConnection()
call. The interface oracle.ucp.jdbc.ConnectionLabelingCallback
is used:
java.util.Properties getRequestedLabels();
getRequestedLabels
is invoked at getConnection()
time when no requested labels are provided and there is an instance registered.
Parent topic: Labeling Connections
Checking Unmatched labels
Connections may have multiple labels, which each uniquely identify the connection based on specified criteria. Use the getUnmatchedConnectionLabels
method to verify which connections do not match the requested label.
This method is used after a connection with multiple labels is reserved from the connection pool and is typically used by a labeling callback. SeegetUnmatchedConnectionLabels
method.
The following code example demonstrates checking for unmatched labels:
. . . String pname = "property1"; String pvalue = "value"; Properties label = new Properties(); label.setProperty(pname, pvalue); . . . Connecion conn = ((WLDataSource)ds).getConnection(label); Properties unmatched = ((LabelableConnection)connection).getUnmatchedConnectionLabels (label); . . .
Parent topic: Labeling Connections
Removing a Connection Label
You can remove a connection label by using the removeConnectionLabel
method.
This method is used after a labeled connection is reserved from the connection pool. See removeConnectionLabel
.
The following code example demonstrates removing a connection label:
. . . String pname = "property1"; String pvalue = "value"; Properties label = new Properties(); label.setProperty(pname, pvalue); Connection conn = ((WLDataSource)ds).getConnection(label); . . . ((LabelableConnection) conn).removeConnectionLabel(pname); . . .
Parent topic: Labeling Connections
Using Initialization and Reinitialization Costs to Select Connections
WebLogic Server provides the following connection properties to identify high cost connections:
-
ConnectionLabelingHighCost
—When greater than 0, connections with a cost value equal to or greater than the property value are considered high-cost connections. The default value isInteger.MAX_VALUE
.For example, if the property value is set to 5, any connection whose calculated cost value from the labeling callback is equal to or greater than 5 is considered a high-cost connection.
-
HighCostConnectionReuseThreshold
—When greater than 0, specifies a threshold of the number of total connections in the pool beyond which Connection Labeling is allowed to reuse high-cost connections in the pool to serve a request. Below this threshold, Connection Labeling either uses an available low-cost connection or creates a brand-new physical connection to serve a request. The default value is 0.For example, if set to 20, Connection Labeling reuses high-cost connections when there are no low-cost connections available and the total connections reach 20.
-
For Generic data sources see Configuring Generic Connection Pool Features.
-
For Active GridLink data sources, see Configuring AGL Connection Pool Features.
Parent topic: Labeling Connections
Considerations When Using Initialization and Reinitialization Costs
This section provides additional considerations when selecting connections based on connection costs:
-
Valid callback registration activates Connection Labeling. Once registered, the connection pool checks for new threshold values at regular intervals and determines:
-
if a connnection has a cost that is equal to or greater than
ConnectionLabelingHighCost
. -
If the number of total connections accounts for the number of active connection creation requests, including restrictions for
MinCapacity
andMaxCapacity
.
-
-
Any labeled connection with cost value of
Integer.MAX_VALUE
is not reused, even if a new threshold is reached. -
There is no requirement not to reuse connections without labels (stateless) in the pool to serve connection requests with labels (labeled requests). Once the
HighCostConnectionReuseThreshold
is reached and Connection Labeling is activated, the pool continues to favor connections without labels (stateless) over creating new physical connections.
Using Connection Labeling with Packaged Applications
WebLogic Server allows callbacks, such as connection labeling and connection initialization, in EAR or WAR files used by a packaged application.
To define an application-packaged callback class in a data source configuration:
-
Define the data source as part of the application.
For example, if the callback implementation classes are packaged in a WAR or defined as part of a shared library that is referenced by the application, the EAR file contains application packaged data source configurations that reference the callback class names in their module descriptors.
-
Specify the application WAR file (that contains the callback implementations) as part of the application
classloader
hierarchy in theweblogic-application.xml
file.For example:
. . . <classloader-structure> <module-ref> <module-uri>appcallbacks.war</module-uri> </module-ref> </classloader-structure>
Considerations When using Labelled Connections in Packaged Applications
WebLogic Server does not support specifying a connection labeling callback or connection initialization callback in the module descriptor for a globally scoped data source system resource when the callback class is packaged in an application. A global data source requires that callback implementation classes be on the WebLogic classpath. However, you can workaround this restriction for an application callback that is packaged in a WAR or EAR by having the application register the callback at runtime using the WLDataSource interface in the Java API Reference for Oracle WebLogic Server.
Parent topic: Labeling Connections