5.2 UCPでのラベリング・コールバックの実装

UCPは、単一のラベルまたは複数のラベルの使用に関係なく、データベース常駐接続プーリング(DRCP)・タグ付けインフラストラクチャを使用して、UCPのラベリングをサポートします。ただし、UCPのみのかわりにUCPおよびDRCPの組合せを使用する場合、複数のラベルを使用した動作は少し異なる可能性があります。

このセクションのトピックは次のとおりです:

5.2.1 UCPでのラベリング・コールバックの使用時期

ラベリング・コールバックは、接続プールでラベル付けされた接続を選択する方法を定義するために使用され、アプリケーションに戻す前に、選択された接続の構成ができます。接続ラベリング機能を使用するアプリケーションは、コールバックを実装する必要があります。

ラベリング・コールバックは、ラベル付けされた接続がリクエストされていながら、リクエストされたラベルと一致する接続がプールにない場合に使用されます。コールバックは、リクエストされたラベルと一致するように再構成するために必要となる作業量が最も少ない接続を特定した後、アプリケーションに戻す前に接続ラベルを更新できるようにします。この節では、以下のトピックについて説明します。

5.2.2 UCPでのラベリング・コールバックの作成

ラベリング・コールバックを作成するには、アプリケーションにoracle.ucp.ConnectionLabelingCallbackインタフェースを実装します。コールバックは、接続プールごとに1つ作成されます。インタフェースでは、次の2つのメソッドが提供されています。

costメソッド

このメソッドは、ラベルマッチングの相違を考慮に入れて、接続の構成コストを見積ります。接続リクエストが発生すると、接続プールはこのメソッドを使用して、最も構成コストが低い接続を選択します。

public int cost(Properties requestedLabels, Properties currentLabels);

configureメソッド

このメソッドは、アプリケーションに戻す前に、選択された接続に対して接続プールによってコールされます。接続の状態を設定し、接続に対してラベルの適用または削除を行うために、このメソッドが使用されます。

public boolean configure(Properties requestedLabels, Connection conn);

接続プール内で使用可能な各接続に対して繰り返します。接続ごとにcostメソッドをコールします。costメソッドの結果は、接続を必要な状態に再構成するために必要なコストの見積りを表すintegerです。値が大きいほど、接続の再構成にはコストがかかります。接続プールは、常に最も低いコスト値の接続を戻します。アルゴリズムは次のとおりです。

  • costメソッドがある接続について0を戻した場合、その接続が適合となります。接続プールは、検出された接続に対してconfigureメソッドをコールせず、その接続をそのまま戻します。

  • costメソッドが0より大きい値を戻した場合、コスト値が0の接続を検出するか、使用可能な接続がなくなるまで繰り返します。

  • すべての使用可能な接続に対して繰り返して、接続の最低コストがInteger.MAX_VALUE(デフォルトでは2147483647)となった場合、プール内に接続リクエストを満たす接続はありません。プールは新しい接続を作成して戻します。プールが最大プール・サイズに達している(新しい接続を作成できない)場合は、SQL例外をスローするか、接続待機タイムアウト属性が指定されていれば待機するかのいずれかです。

  • すべての使用可能な接続に対して繰り返して、接続の最低コストがInteger.MAX_VALUEよりも低い場合、その接続に対してconfigureメソッドをコールし、その接続を戻します。複数の接続がInteger.MAX_VALUEを下回る場合は、最低コストの接続を戻します。

注意:

コスト0は、requestedLabelscurrentLabelsが等しいという意味ではありません。

5.2.2.1 UCPでのラベリング・コールバックの例

次の例では、costconfigureの両メソッドを実装する単純なラベリング・コールバックの実装を示します。このコールバックは、特定のトランザクション分離レベルで初期化されるラベル付けされた接続の検出に使用されます。

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;
  }
}

5.2.3 UCPでのラベリング・コールバックの登録

プール対応のデータソースは、ラベリング・コールバックを登録するためのregisterConnectionLabelingCallback(ConnectionLabelingCallback callback)メソッドを備えています。1つの接続プールに登録できるコールバックは1つのみです。次の例では、MyConnectionLabelingCallbackクラスに実装されているラベリング・コールバックの登録を示します。

MyConnectionLabelingCallback callback = new MyConnectionLabelingCallback();
pds.registerConnectionLabelingCallback( callback );

5.2.4 UCPでのラベリング・コールバックの削除

プール対応のデータソースは、ラベリング・コールバックを削除するためのremoveConnectionLabelingCallback()メソッドを備えています。次の例では、ラベリング・コールバックの削除を示します。

pds.removeConnectionLabelingCallback( callback );