ヘッダーをスキップ
Oracle TimesTen In-Memory Database TTClassesガイド
リリース6.0
B25771-01
  目次へ
目次
索引へ
索引

前へ
前へ
次へ
次へ
 

トランザクション境界におけるXLA更新の確認

XLAは、データベース内の特定の表に変更通知を返すとともに、それらのデータベース変更のトランザクション境界に関する情報も返します。この項では、トランザクション境界のみで更新を確認する方法について説明します。これはXLAアプリケーションで一般的な要件です。

TTClasses/XLAプログラムの一般的なメイン・ループは、次のようなものです。

例1.3 一般的なTTClasses/XLAメイン・ループ
TTXlaPersistConnection conn; // XLA connection
TTXlaTableList list(&conn); // tables being monitored
ttXlaUpdateDesc_t ** arry; // ptr to returned XLA recs
TTStatus stat;
int records_fetched;
// ...
loop {
// fetch the updates
// could also be conn.fetchUpdates(...);
conn.fetchUpdatesWait(&arry, MAX_RECS_TO_FETCH,
&records_fetched, ...);
// Interpret the updates
for(j=0;j < records_fetched;j++){
ttXlaUpdateDesc_t *p;
p = arry[j];
list.HandleChange(p, stat);
} // end for each record fetched
// periodically call ackUpdates()
if (some condition is reached) {
conn.ackUpdates(stat) ;
}
} // loop

HandleChange()メソッド内では、レコードがinsert/update/deleteであるかどうかに応じて、<HandleInsert()、HandleUpdate()、HandleDelete()>のいずれかがコールされます。

XLAレコードが特定のトランザクションにおける最後のレコードかどうかを示すフラグにユーザーがアクセスできるのは、HandleChange()内です。

したがって上のループでは、トランザクション境界に関する情報によってconn.ackUpdates()をコールする時点を変更できるように、HandleChange()メソッドがその情報をループに渡す方法はありません。

1トランザクションにつきレコードが数個しかない一般的な状況では、これは問題になりません。これは、fetchUpdates()またはfetchUpdatesWait()メソッドで最大1000個のレコードを返すようXLAに要求しても、通常は数個のレコードのみが返されるためです。XLAはできるだけ速くレコードを返し、データベース内で膨大な数のトランザクションが発生していても、XLAレコードを一度に数個ずつ、かなり短時間で取り出すことができます。それらのXLAレコードを一度に数個ずつ取り出す場合は、通常、TimesTen XLAによって、最後に返されるレコードが確実にトランザクション境界上のレコードになります。

つまり、XLAに1000個のレコードを要求して、XLAが15個しか返さない場合は、15番目のレコードがほぼ確実にトランザクションの終了に当たります。ただし、これは100%保証されるものではありません。

XLAは、完了済トランザクション(おそらくXLAレコードの単一バッチにおける複数のトランザクション)でレコードのバッチが終了すること、またはレコードのバッチに部分トランザクションが含まれ、同じバッチ内に完了済トランザクションがないこと、およびトランザクション境界に達するまで、その単一トランザクションについて後続のXLAレコードのバッチが返されることを保証します。

入念なXLAアプリケーションでは、XLAレコードのバッチにおける最後のレコードにトランザクション境界があるかどうか検証し、そのトランザクション境界のみでackUpdates()をコールする必要があります。

これが常に問題となるケースは、大きな行の操作を処理する場合です。データベースに対してバルクinsert/update/delete操作を実行した場合、XLAアプリケーションが1000個のレコードを要求すると、1000個のレコードすべて(または1000個未満)を受信する可能性があり、XLAを介して最後に返されるレコードには、おそらくトランザクション終了フラグが設定されていません。実際、トランザクションによって10,000個のレコードが変更された場合、トランザクション境界に達するまでに1000個のXLAレコードのブロックを最低10個フェッチする必要があることは明白です。繰り返しますが、入念なXLAアプリケーションでは、トランザクション境界に達したかどうかチェックし、達した場合にのみackUpdates()をコールする必要があります。

もちろん、トランザクション境界ごとにackUpdates()をコールするのは賢明ではありません。ackUpdates()は相対的に負荷の高い(低速な)操作のためです。しかし、入念なXLAアプリケーションでは、アプリケーション、システムまたはデータベースに障害が発生した場合、システムのリカバリ時にXLAブックマークがトランザクションの途中ではなく先頭に置かれるよう、確実にトランザクション境界のみでこのメソッドをコールする必要があります。

そのため、HandleChange()メソッドには、HandleChange()とメインXLAループとの間で情報の受渡しを可能にする第3のパラメータがあります。前述のループを次のループと比較してください。

例1.4 トランザクション境界が監視される、改良済のXLAメイン・ループ
TTXlaPersistConnection conn; // XLA connection
TTXlaTableList list(&conn); // tables being monitored
ttXlaUpdateDesc_t ** arry; // ptr to returned XLA recs
TTStatus stat;
int records_fetched;
int do_acknowledge;
// ...
loop {
// fetch the updates
// could also be conn.fetchUpdates(...);
conn.fetchUpdatesWait(&arry, MAX_RECS_TO_FETCH,
&records_fetched, ...);
do_acknowledge = FALSE;
// Interpret the updates
for(j=0;j < records_fetched;j++){
ttXlaUpdateDesc_t *p;
p = arry[j];
list.HandleChange(p, stat, &do_acknowledge);
} // end for each record fetched
// periodically call ackUpdates()
if (do_acknowledge == TRUE
/* and some other conditions ... */ ) {
conn.ackUpdates(stat) ;
}
} // loop

このコードでわかるように、ackUpdates()は、このXLAレコードのバッチがトランザクション境界にあることがdo_acknowledgeフラグによって示された場合にのみコールされます。

XLAメイン・ループのこの変更に加え、関数isXLACommitRecord(ttXlaUpdateDesc_t*)を使用するようHandleChange()メソッドを記述(上書き)する必要があります。

TTClassesデモ<demo/ttclasses/xlademo.cpp>は、HandleChange()メソッドの書換えを示しています。このデモ・プログラムを参照および実行して、XLAのトランザクション終了フラグの監視およびそれに応じた処理の実行方法を調べてください。