XLAのTTClassesでの使用
この項では、TimesTen Classicのトランザクション・ログAPI (XLA)の使用について説明します。
TimesTen XLAについて
XLAとは、指定したデータベース表への変更についてTimesTenを監視して、それに該当する変更の通知をリアルタイムで受信するアプリケーションの実装を可能にする関数のセットです。
XLAの主な目的は、トリガーに対する、高性能で非同期の代替手段を提供することです。
XLAは、データベース内の特定の表への変更の通知を返すとともに、これらのデータベース変更のトランザクション境界に関する情報も返します。この項では、トランザクション境界を使用しない例および使用する例を使用して、トランザクション境界のみでの更新(XLAアプリケーションでの一般的な要件)を確認する方法を示します。
重要なノート:
-
ODBCドライバ・マネージャ使用時の考慮事項(Windows)で説明したように、XLA機能はODBCドライバ・マネージャに接続されたアプリケーションでは使用できません。
-
XLAブックマークがスタックした場合(これは先にブックマークを削除したり変更追跡を無効にしない状態で、XLAアプリケーションが予期せず停止したか、切断されると発生する可能性があります)、トランザクション・ログ・ファイルが過度に蓄積されていることがあります。この蓄積によって、ファイル・システム領域が一杯になる場合があります。Oracle TimesTen In-Memory Databaseオペレーション・ガイドのトランザクション・ログ・ファイルの蓄積の監視を参照してください。
その他のノート:
-
LOB列がある表をサブスクライブすることは可能ですが、LOB値自体の情報は入手できません。
-
LOBを含む列は空(長さ0)またはnull(値が実際に
NULL
の場合)と通知されます。null列とnull以外の列の違いは、この方法で判別できます。 -
XLAリーダーは、インメモリー列ベースの圧縮を使用する表をサブスクライブできません。
Oracle TimesTen In-Memory Database C開発者ガイドのXLAおよびTimesTenイベント管理を参照してください。また、TimesTen Classicクイック・スタートで提供されるTTClassesサンプル・アプリケーションにXLAアプリケーションが含まれています。TimesTenクイック・スタートおよびサンプル・アプリケーションについてを参照してください。
トランザクション境界を使用しないXLA更新の確認
HandleChange()
メソッド内では、レコードがinsertか、updateか、deleteかに応じて、HandleInsert()
、HandleUpdate()
、HandleDelete()
のいずれかの適切なメソッドがコールされます。
XLAレコードが特定のトランザクションにおける最後のレコードかどうかを示すフラグにユーザーがアクセスできるのは、HandleChange()
内です。そのため、この項に示す例のループでは、HandleChange()
メソッドがトランザクション境界に関する情報をループに渡す方法がないため、この情報でconn.ackUpdates()
をコールするタイミングを変更できません。
1つのトランザクションにつきレコードが数個しかない一般的な状況では、これは問題になりません。fetchUpdatesWait()
コールで最大1000個のレコードを返すようXLAに要求しても、通常は数個のレコードが返されるだけです。XLAはできるだけ速くレコードを返し、データベース内で膨大な数のトランザクションが発生していても、通常はXLAレコードを一度に数個ずつ、短時間で取得することができ、XLAは最後に返されたレコードがトランザクション境界上にあることを確認します。たとえば、XLAに1000個のレコードを要求して、15個しか返されない場合は、15番目のレコードがほぼ確実にトランザクションの終了に当たります。
XLAによって、次のいずれかが保証されます。
-
完了したトランザクション(おそらくXLAレコードの単一バッチにおける複数のトランザクション)でレコードのバッチが終了すること。
または
-
レコードのバッチに部分トランザクションが含まれ、同じバッチ内に完了したトランザクションがないこと、およびトランザクション境界に達するまで、その単一トランザクションの後続のXLAレコードのバッチが返されること。
次の例に、TTClassesのXLAプログラムの一般的なメイン・ループを示します。(また、シグナル・ハンドラも存在すると仮定しています。)
TTXlaPersistConnection conn; // XLA connection
TTXlaTableList list(&conn); // tables being monitored
ttXlaUpdateDesc_t ** arry; // pointer to returned XLA records
int records_fetched;
// ...
while (!signal_received) {
// fetch the updates
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, NULL);
} // end for each record fetched
// periodically call ackUpdates()
if (/* some condition is reached */) {
conn.ackUpdates();
}
}
トランザクション境界におけるXLA更新の確認
XLAアプリケーションでは、XLAレコードのバッチにおける最後のレコードにトランザクション境界があるかどうか検証し、このトランザクション境界のみでackUpdates()
をコールする必要があります。このように、アプリケーション、システムまたはデータベースが失敗した場合、システムのリカバリ後はXLAブックマークがトランザクションの始めにあることなります。
これは、操作に多数の行が関連する場合に特に重要です。データベースに対して挿入、更新、削除のバルク操作を実行する場合に、XLAアプリケーションが1000個のレコードを要求すると、1000個のレコードすべてが受信される場合もされない場合もあります。XLAを介して最後に返されるレコードには、おそらくトランザクション終了フラグが設定されていません。実際、トランザクションによって10,000個のレコードが変更された場合、トランザクション境界に達するまでに1000個のXLAレコードのブロックを最低でも10個フェッチする必要があります。
ただし、ackUpdates()
は相対的に負荷の高い操作であるため、トランザクション境界ごとにackUpdates()
をコールすることはお薦めしません。ユーザーは、リカバリ時間およびファイル・システム領域の要件において、システムの全体的なスループットのバランスをとる必要があります。(XLAにそのログ・ファイルを参照するブックマークがある場合、チェックポイント操作ではTimesTenのトランザクション・ログ・ファイルを削除できない点に注意してください。Oracle TimesTen In-Memory DatabaseリファレンスのttLogHoldsを参照してください。システムのスループット、リカバリ時間およびファイル・システム領域の要件に応じ、アプリケーションによっては、1分ごとにackUpdates()
を1回または複数回コールすることが適切である場合もあれば、1時間に1回または数回しかコールする必要がない場合もあります。
HandleChange()
メソッドには、HandleChange()
とメインXLAループとの間で情報の受渡しを可能にする第2のパラメータがあります。前の項に示した例と次の例について、特に、do_acknowledge
の設定とHandleChange()
コールの&do_acknowledge
パラメータを比較してください。
この例では、ackUpdates()
は、このXLAレコードのバッチがトランザクション境界にあることがdo_acknowledge
フラグによって示された場合にのみコールされます。(この例では、シグナル・ハンドラも存在すると仮定しています。)
TTXlaPersistConnection conn; // XLA connection
TTXlaTableList list(&conn); // tables being monitored
ttXlaUpdateDesc_t ** arry; // ptr to returned XLA recs
int records_fetched;
int do_acknowledge;
int j;
// ...
while (!signal_received) {
// fetch the updates
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, &do_acknowledge);
} // end for each record fetched
// periodically call ackUpdates()
if (do_acknowledge == TRUE /* and some other conditions ... */ ) {
conn.ackUpdates();
}
}
このXLAのメイン・ループに対する変更に加えて、HandleChange()
メソッドをオーバーロードして、2つのパラメータ(ttXlaUpdateDesc_t*, void*
pData
)
を持つようにする必要があります。HandleChange()を参照してください。TimesTen Classicクイック・スタートのxlasubscriber1
サンプル・アプリケーションは、pData
パラメータの使用方法を示しています。(TimesTenクイック・スタートおよびサンプル・アプリケーションについてを参照してください。)
XLAシステム権限
システム権限XLA
は、XLAリーダーとしてTimesTenに接続する場合(CREATE SESSION
権限も必要)、XLA関連のTimesTen C関数を実行する場合、およびXLA関連のTimesTen組込みプロシージャを実行する場合など、すべてのXLA機能で必要になります。
Oracle TimesTen In-Memory Database C開発者ガイドのXLAシステム権限を参照してください。
ノート:
XLA
権限を持つユーザーは、データベースで実行されるすべてのDML文の通知を受信できます。そのため、XLA
権限を持つユーザーは、この権限なしにはアクセスが許可されないデータベース・オブジェクトに関する情報を取得できるようになります。実際、XLA
権限は、実質的にSELECT ANY TABLE
、SELECT ANY VIEW
およびSELECT ANY SEQUENCE
権限と同じです。