WebSphere® eXtreme Scale トランザクションが、バックエンド・トランザクションの開始前に終了するため、トランザクションが誤って正常となる場合があります。
バックアップ・マップには存在しないが、バックエンド・データベースに存在するエントリーを eXtreme Scale トランザクションに挿入すると、重複キーになることになりますが、eXtreme Scale トランザクションは成功します。しかしながら、後書きスレッドがバックエンド・データベースにそのオブジェクトを挿入するトランザクションは、重複キー例外で失敗します。
このような更新、あるいはその他失敗したバックエンド更新は、失敗した後書き更新となります。 失敗した後書き更新は、失敗した後書き更新マップに保管されます。このマップは、失敗した更新のイベント・キューとして機能します。更新のキーは、固有の Integer オブジェクトで、値は、FailedUpdateElement のインスタンスになります。失敗した後書き更新マップは、エビクターによって構成されます。エビクターは、レコードを挿入後 1 時間経過すると除去します。このため、失敗した更新レコードは、1 時間以内に取得されないと失われます。
失敗した後書き更新マップのエントリーを取り出すには、ObjectMap API を使用できます。失敗した後書き更新マップの名前は IBM_WB_FAILED_UPDATES_<map name> です。各後書きシステム・マップの接頭部名については、WriteBehindLoaderConstants API の資料を参照してください。以下に例を示します。
process failed - example code
ObjectMap failedMap = session.getMap(
WriteBehindLoaderConstants.WRITE_BEHIND_FAILED_UPDATES_MAP_PREFIX + "Employee");
Object key = null;
session.begin();
while(key = failedMap.getNextKey(ObjectMap.QUEUE_TIMEOUT_NONE)) {
FailedUpdateElement element = (FailedUpdateElement) failedMap.get(key);
Throwable throwable = element.getThrowable();
Object failedKey = element.getKey();
Object failedValue = element.getAfterImage();
failedMap.remove(key);
// Do something interesting with the key, value, or exception.
}
session.commit();
getNextKey 呼び出しは、 各 eXtreme Scale トランザクションごとに特定の 1 つの区画について作業します。 分散環境では、すべての区画からキーを取得するため、以下の例に示すように複数のトランザクションを開始する必要があります。
getting keys from all partitions - example code
ObjectMap failedMap = session.getMap(
WriteBehindLoaderConstants.WRITE_BEHIND_FAILED_UPDATES_MAP_PREFIX + "Employee");
while (true) {
session.begin();
Object key = null;
while(( key = failedMap.getNextKey(5000) )!= null ) {
FailedUpdateElement element = (FailedUpdateElement) failedMap.get(key);
Throwable throwable = element.getThrowable();
Object failedKey = element.getKey();
Object failedValue = element.getAfterImage();
failedMap.remove(key);
// Do something interesting with the key, value, or exception.
}
Session.commit();
}
後書きトランザクションが失敗した場合、それを検出し、ログに記録することが重要です。後書きを使用するアプリケーションはすべて、失敗した後書き更新を処理するウォッチャーを実装する必要があります。 これによって、アプリケーションが正しくない更新マップ内のレコードを処理することが期待されるため、それらが除去されずに潜在的なメモリー不足になることを防ぐことができます。
以下のコードは、そのようなウォッチャー (ダンパー) の接続方法を示しています。これは、ObjectGrid 記述子 XML にスニペットとして追加する必要があります。
<objectGrid name="Grid">
<bean id="ObjectGridEventListener" className="utils.WriteBehindDumper"/>
ObjectGridEventListener Bean が追加されていることがわかります。これは、上記で取り上げた後書きウォッチャーです。このウォッチャーは、JVM 内のすべてのプライマリー断片のマップと対話し、後書きが使用可能になったものを検索します。後書きが使用可能になったものを検出すると、ウォッチャーは最大 100 の不適切な更新をログに記録しようとします。ウォッチャーは、プライマリー断片が別の JVM に移動されるまで、その断片を監視します。後書きを使用するすべてのアプリケーションは、これと似たウォッチャーを使用する必要があります。使用しないと、このエラー・マップが除去されないため、Java 仮想マシン がメモリー不足になります。
詳しくは、例: 後書きダンパー・クラスの作成を参照してください。