トランザクションのライフサイクル・イベントの管理のためのプラグイン

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

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

目的

OptimisticCallback インターフェースを使用して、マップの値としてオプティミスティック比較演算を提供します。 オプティミスティック・ロック・ストラテジーを使用するときは、OptimisticCallback の実装が必要です。 WebSphere® eXtreme Scale はデフォルトの 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 インターフェース内の各メソッドについての説明または考慮事項があります。

NULL_OPTIMISTIC_VERSION

この特殊値は、アプリケーション提供の OptimisticCallback 実装の代わりにデフォルトの OptimisticCallback 実装が使用される場合に、getVersionedObjectForValue メソッドによって戻されます。

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 メソッド

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 構成方法

前の例の EmployeeOptimisticCallbackImpl オブジェクトは、OptimisticCallback インターフェースを実装する必要があります。 次の例に示すように、アプリケーションは、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>