キャッシュ・オブジェクトのバージョン管理と比較のためのプラグイン

オプティミスティック・ロック・ストラテジーを使用しているときは、OptimisticCallback プラグインによってキャッシュ・オブジェクトのバージョン管理および比較操作をカスタマイズすることができます。

com.ibm.websphere.objectgrid.plugins.OptimisticCallback インターフェースを実装するプラグ可能オプティミスティック・コールバック・オブジェクトを用意できます。エンティティー・マップの場合、ハイパフォーマンス OptimisticCallback プラグインが自動的に構成されます。

目的

OptimisticCallback インターフェースを使用して、マップの値としてオプティミスティック比較演算を提供します。オプティミスティック・ロック・ストラテジーを使用するときは、OptimisticCallback プラグインが必要です。 この製品 はデフォルトの OptimisticCallback 実装を提供しています。ただし、通常、アプリケーションは独自の OptimisticCallback インターフェースの実装をプラグインする必要があります。

デフォルト実装

eXtreme Scale フレームワークは、 OptimisticCallback インターフェースのデフォルト実装を提供します。この実装は、アプリケーション提供の OptimisticCallback オブジェクトをアプリケーションがプラグインしない場合に使用します。 デフォルト実装は、値のバージョン・オブジェクトとして、常に特殊値 NULL_OPTIMISTIC_VERSION を戻し、バージョン・オブジェクトの更新は行いません。このアクションにより、オプティミスティック比較は「ノーオペレーション」関数になります。 オプティミスティック・ロック・ストラテジーを使用しているとき、たいていの場合、「ノーオペレーション」関数が発生することは望まないと思われます。ご使用のアプリケーションが OptimisticCallback インターフェースを実装し、独自の OptimisticCallback 実装をプラグインする必要がある場合、 デフォルト実装は使用しません。ただし、デフォルト提供の OptimisticCallback 実装が有用なシナリオが、少なくとも 1 つ存在します。次のような状態について考えてみます。
  • ローダーがバックアップ・マップ用にプラグインされている。
  • ローダーが、OptimisticCallback プラグインからの支援なしに、 オプティミスティック比較を実行する方法を認識している。
ローダーが、OptimisticCallback オブジェクトからの支援なしで、オプティミスティック・バージョン管理を実行できる方法について考えてみます。 ローダーは、値クラス・オブジェクトを認知し、オプティミスティック・バージョン管理の値としてどの値オブジェクトのフィールドを使用するかを認識しています。例えば、従業員マップの値オブジェクトに対して次のインターフェースを使用するとします。
public interface Employee
{
    // Sequential sequence number used for optimistic versioning.
    public long getSequenceNumber();
    public void setSequenceNumber(long newSequenceNumber);
    // Other get/set methods for other fields of Employee object.
}

この例では、ローダーは、getSequenceNumber メソッドを使用して、Employee 値オブジェクトの現行バージョン情報を取得できることを認識しています。 ローダーは、戻り値を増分して、新規 Employee 値で永続ストレージを更新する前に、新規バージョン番号を生成します。 Java Database Connectivity (JDBC) ローダーの場合、過剰 SQL UPDATE ステートメントの WHERE 文節内の現行シーケンス番号が使用され、新規生成シーケンス番号を使用して、シーケンス番号列が新規シーケンス番号の値に設定されます。 このほかにも、オプティミスティック・バージョン管理に使用できる非表示の列を自動的に 更新するなんらかのバックエンド提供の関数をローダーが利用する可能性があります。

状況によっては、ストアード・プロシージャーまたはトリガーを使用して、バージョン情報が入っている列を保守できるようにすることもあります。 ローダーが、オプティミスティック・バージョン情報を保守するためにこれらの技法のいずれかを使用している場合は、アプリケーションが OptimisticCallback 実装を提供する必要はありません。デフォルトの OptimisticCallback 実装は、ローダーが OptimisticCallback オブジェクトからの支援なしにオプティミスティック・バージョン管理を処理できるため、このシナリオでは便利です。

エンティティーのデフォルト実装

エンティティーは、タプル・オブジェクトを使用して、ObjectGrid に保管されます。 デフォルトの OptimisticCallback 実装の振る舞いは、非エンティティー・マップに対する振る舞いと似ています。 ただし、エンティティー内のバージョン・フィールドは、エンティティー記述子 XML ファイルの @Version アノテーションまたはバージョン属性を使用して識別されます。

バージョン属性の型は、int、Integer、short、Short、long、Long、java.sql.Timestamp のいずれかになります。エンティティーにはバージョン属性を 1 つだけ定義することができます。 バージョン属性は構成時にのみ設定するようにしてください。 エンティティーが永続化されると、バージョン属性の値は変更してはなりません。

バージョン属性が構成されず、オプティミスティック・ロック・ストラテジーが使用される場合、タプルの全体の状態を使用して、タプル全体が暗黙的にバージョン設定されますが、これははるかに高コストになります。

以下の例では、Employee エンティティーに SequenceNumber という long バージョン属性が設定されています。
@Entity
public class Employee
{
private long sequence;
    // Sequential sequence number used for optimistic versioning.
    @Version
    public long getSequenceNumber() {
        return sequence;
    }
    public void setSequenceNumber(long newSequenceNumber) {
        this.sequence = newSequenceNumber;
    }
    // Other get/set methods for other fields of Employee object.
}

OptimisticCallback プラグインの記述

OptimisticCallback プラグインは、OptimisticCallback インターフェースを実装し、共通 ObjectGrid プラグイン規則に準拠する必要があります。 詳しくは、OptimisticCallback インターフェースを参照してください。

次のリストには、OptimisticCallback インターフェース内の各メソッドについての説明または考慮事項があります。

NULL_OPTIMISTIC_VERSION

この特殊値は、OptimisticCallback 実装がバージョン検査を必要としない場合に、getVersionedObjectForValue メソッドによって戻されます。 com.ibm.websphere.objectgrid.plugins.builtins.NoVersioningOptimisticCallback クラスの組み込みプラグイン実装では、このプラグイン実装を指定するとバージョン管理が使用不可になるため、この値が使用されます。

getVersionedObjectForValue メソッド

getVersionedObjectForValue メソッドは、バージョン管理のために使用できる値のコピーまたは値の属性を戻すことがあります。 このメソッドは、オブジェクトがトランザクションに関連付けられるたびに呼び出されます。 ローダーがバックアップ・マップ内にプラグインしていない場合、 バックアップ・マップは、コミット時刻にこの値を使用してオプティミスティック・バージョン管理比較を行います。 オプティミスティック・バージョン管理比較は、このトランザクションがこのトランザクションによって変更されたマップ・エントリーに最初にアクセスした後でバージョンが変更されていないことを確認するために、バックアップ・マップによって使用されます。 別のトランザクションが既にこのマップ・エントリーのバージョンを変更している場合、バージョン比較は失敗し、バックアップ・マップは OptimisticCollisionException 例外を表示して、トランザクションを強制的にロールバックします。 ローダーがプラグインされている場合、 バックアップ・マップはオプティミスティック・バージョン管理情報を使用しません。 代わりに、ローダーは、オプティミスティック・バージョン管理比較を行い、 必要に応じてバージョン管理情報を更新する責任があります。 ローダーは通常、ローダーの batchUpdate メソッドに渡される LogElement から、初期バージョン管理オブジェクトを取得します。このオブジェクトは、フラッシュ操作が発生するか、トランザクションがコミットされたときに呼び出されます。

次のコードは、EmployeeOptimisticCallbackImpl オブジェクトによって使用される実装を示しています。
public Object getVersionedObjectForValue(Object value)
{
    if (value == null)
    {
        return null;
    }
    else
    {
        Employee emp = (Employee) value;
        return new Long( emp.getSequenceNumber() );
    }
}

前の例に示すように、sequenceNumber 属性は、ローダーが予期するように、java.lang.Long オブジェクト内に戻されます。これは、ローダーの作成者と同一人物が EmployeeOptimisticCallbackImpl を作成したか、 EmployeeOptimisticCallbackImpl を実装した人物と協力して作業を行ったか (例えば、getVersionedObjectForValue メソッドによって戻された値に合意した) のいずれかであることを示しています。 デフォルトの OptimisticCallback プラグインは、特殊値 NULL_OPTIMISTIC_VERSION をバージョン・オブジェクトとして戻します。

updateVersionedObjectForValue メソッド

このメソッドは、トランザクションが値を更新し、新バージョンのオブジェクトが必要になるたびに呼び出されます。 getVersionedObjectForValue メソッドがこの値の属性を戻した場合、このメソッドは通常、属性値を新バージョンのオブジェクトに更新します。 getVersionedObjectForValue メソッドがこの値のコピーを戻した場合、このメソッドは通常、いかなるアクションも完了しません。 デフォルトの OptimisticCallback プラグインは、getVersionedObjectForValue のデフォルト実装がバージョン・オブジェクトとして常に特殊値 NULL_OPTIMISTIC_VERSION を戻すため、このメソッドではいかなるアクションも完了しません。 次の例は、OptimisticCallback セクションで使用される EmployeeOptimisticCallbackImpl オブジェクトによって使用される実装を示しています。
public void updateVersionedObjectForValue(Object value)
{
    if ( value != null )
    {
        Employee emp = (Employee) value;
        long next = emp.getSequenceNumber() + 1;
        emp.updateSequenceNumber( next );
    }
}

前の例で示すように、sequenceNumber 属性は、次に getVersionedObjectForValue メソッドが呼び出されたときに、戻される java.lang.Long 値が長整数値を持つように、1 ずつ増分されます。この長整数値は、元のシーケンス番号の値に 1 を加えたもの (例えば、この従業員インスタンスの次のバージョン値) です。 この例は、ローダーを作成者が EmployeeOptimisticCallbackImpl の作成者と同一人物であるか、 EmployeeOptimisticCallbackImpl を実装した人物と協力して作業を行ったかのいずれかであることを示しています。

serializeVersionedValue メソッド

このメソッドは、指定されたストリームにバージョン値を書き込みます。 実装によっては、バージョン値を使用して、オプティミスティック更新の衝突を識別することができます。 一部の実装では、バージョン値は元の値のコピーです。 それ以外の実装では、値のバージョンを示すシーケンス番号またはその他のいくつかのオブジェクトがあります。 実際の実装が不明であるため、このメソッドは適切なシリアライゼーションを実行するために提供されます。 デフォルト実装は writeObject メソッドを呼び出します。

inflateVersionedValue メソッド

このメソッドは、バージョン値のシリアライズ・バージョンを取り、実際のバージョン値オブジェクトを戻します。 実装によっては、バージョン値を使用して、オプティミスティック更新の衝突を識別することができます。 一部の実装では、バージョン値は元の値のコピーです。 それ以外の実装では、 値のバージョンを示すシーケンス番号またはその他のいくつかのオブジェクトがあります。 実際の実装が不明であるため、このメソッドは適切なデシリアライゼーションを行うために提供されます。 デフォルト実装は readObject メソッドを呼び出します。

アプリケーション提供の OptimisticCallback オブジェクトの使用

アプリケーション提供の OptimisticCallback オブジェクトを BackingMap 構成に追加する場合、XML 構成とプログラマチック構成の 2 つの方法があります。

OptimisticCallback オブジェクトのプログラマチックなプラグイン

次の例は、ローカル grid1 ObjectGrid インスタンス内の従業員のバックアップ・マップ用に、アプリケーションで OptimisticCallback オブジェクトをプログラマチックにプラグインする方法を示しています。
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
import com.ibm.websphere.objectgrid.ObjectGridManager;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.BackingMap;
ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager();
ObjectGrid og = ogManager.createObjectGrid( "grid1" );
BackingMap bm = dg.defineMap("employees");
EmployeeOptimisticCallbackImpl cb = new EmployeeOptimisticCallbackImpl();
bm.setOptimisticCallback( cb );

OptimisticCallback オブジェクトをプラグインするための XML 構成方法

次の例に示すように、アプリケーションは、XML ファイルを使用して、その OptimisticCallback オブジェクトをプラグインすることができます。
<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
 xmlns="http://ibm.com/ws/objectgrid/config">
<objectGrids>
    <objectGrid name="grid1">
        <backingMap name="employees" pluginCollectionRef="employees" lockStrategy="OPTIMISTIC" />
    </objectGrid>
</objectGrids>

<backingMapPluginCollections>
    <backingMapPluginCollection id="employees">
        <bean id="OptimisticCallback" className="com.xyz.EmployeeOptimisticCallbackImpl" />
    </backingMapPluginCollection>
</backingMapPluginCollections>
</objectGridConfig>