双方向レプリケーション・スキームで構成されたデータ・ストアの表では、レプリケーション競合が発生する可能性があります(「一般ワークロード設定」を参照)。レプリケーション競合は、双方向レプリケーション・データ・ストアでアプリケーションが同じデータ項目に対して同時にUPDATE、INSERTまたはCREATE VIEW処理を開始した場合に発生します。特別な手順を実行しなかった場合、各データ・ストアが他方のデータ・ストアで最後に行われた更新と一致しなくなる可能性があります。
次の異なる3つのタイプのレプリケーション競合が発生する可能性があります。
更新、一意、削除競合の検出時にTimesTenで作成されるレポートの例は、「競合のレポート」を参照してください。
図8.1に、次の表に示す状況で値Xに対して発生する更新競合の結果を示します。
図8.1 更新競合
更新競合または挿入競合を確認しないでそのままにしておくと、マスターとサブスクライバのデータ・ストアは互いに同期しなくなります。正しいデータ・ストアを判断することが困難、または不可能になる場合さえあります。
更新競合では、トランザクションで多数のデータ項目が更新された場合でも、一部の項目で競合が発生する可能性があります。トランザクションの結果は、レプリケーションによって少し上書きされるのみで、ほとんどが競合の影響を受けません。このような競合を無視すると、アプリケーション・データのトランザクションの一貫性が損なわれます。
更新競合が発生した場合、および行のバージョンごとに更新された列が異なる場合は、行に対する主キー以外のフィールドがレプリケート表間で異なる場合があります。
TimesTenレプリケーションには、同時更新または挿入に対処するためにタイムスタンプ・ベースの競合解消が含まれています。タイムスタンプ・ベースの競合解消を使用することで、レプリケート・データ・ストアの同期およびトランザクションの一貫性を維持できます。
図8.2に、次の表に示す状況でRow 4に対して発生する削除/更新競合の結果を示します。
図8.2 更新/削除競合
TimesTenは削除/更新競合を検出およびレポートすることはできますが、解消することはできません。このような状況では、マスターとサブスクライバのデータ・ストアは互いに同期しなくなります。
TimesTenでは、このような競合が発生した後のデータ・ストア間の同期は保証できませんが、最新のトランザクションが各データ・ストアに適用されることは保証されます。削除のタイムスタンプが更新のタイムスタンプより新しい場合は、各データ・ストアで行が削除されます。更新のタイムスタンプが削除のタイムスタンプより新しい場合は、ローカル・データ・ストアで行が更新されます。ただし、その行は他方のデータ・ストアでは削除されているため、レプリケート対象の更新は破棄されます。レポートの例は、「削除/更新競合のレポート」を参照してください。
競合が発生する可能性があるレプリケート表の場合は、BINARY(8)型の特別な列を持つ表を作成して、行を挿入または最後に更新した時刻を示すタイムスタンプ値を保持します。特定の行を変更するたびにこの列にタイムスタンプ値が自動的に挿入されるようにTimesTenを設定できます(「タイムスタンプ比較の設定」を参照)。
レプリケーションでのタイムスタンプ列の計算方法は、システムによって異なります。
TimesTenでは、トランザクションが更新を実行するたびにシステムによって返される時間値がレコードのINSERTまたはUPDATE時間として使用されます。そのため、単一のトランザクションによって挿入または更新された行が、異なるタイムスタンプ値を受信する場合があります。
マスターから受信した更新を適用する場合、サブスクライバ・データ・ストアのレプリケーション・エージェントは、次の方法でタイムスタンプによる解消を実行します。
タイムスタンプ比較を設定するには、次の手順を実行します。
レプリケート表でタイムスタンプ比較を使用するには、タイムスタンプ値を保持するBINARY(8)型のNULL値可能列を指定する必要があります。タイムスタンプ列を主キーまたは索引の一部にすることはできません。例8.1に、タイムスタンプ値を保持するBINARY(8)型の列TSTAMPを含むREPL.TAB表を示します。
CREATE TABLE REPL.TAB (COL1 SMALLINT NOT NULL, COL2 SMALLINT NOT NULL, TSTAMP BINARY(8), PRIMARY KEY (COL1));レプリケート表にタイムスタンプ値が定義されていない場合は、タイムスタンプ比較を実行して競合を検出できません。かわりに、各サイトのデータベース内の行の値に、ローカル・アプリケーションまたはレプリケーションによって行に最後に適用された更新が反映されます。
レプリケーション・スキームの設定時に、CREATE REPLICATION文の表のELEMENT記述にCHECK CONFLICTS句を含めることによって、TABLE要素にタイムスタンプ比較を設定できます。
CREATE REPLICATION文の構文については、『Oracle TimesTen In-Memory Database APIおよびSQLリファレンス・ガイド』のSQL文に関する章を参照してください。次に、レプリケーション・スキームの設定時にCHECK CONFLICTSを使用する方法の例を示します。
この例では、例1.25の双方向レプリケーション・スキームに自動タイムスタンプ比較を設定します。WEST_DSNおよびEAST_DSNというDSNで、タイムスタンプ列TSTAMPを含む表REPL.ACCOUNTSをレプリケートするWESTDSデータ・ストアおよびEASTDSデータ・ストアを設定します。比較に失敗した場合は、タイムスタンプが古いほうの更新を含むトランザクションを破棄します。
CREATE REPLICATION REPL.R1 ELEMENT ELEM_ACCOUNTS_1 TABLE REPL.ACCOUNTS CHECK CONFLICTS BY ROW TIMESTAMP COLUMN TSTAMP UPDATE BY SYSTEM ON EXCEPTION ROLLBACK WORK MASTER WESTDS ON "WESTCOAST" SUBSCRIBER EASTDS ON "EASTCOAST" ELEMENT ELEM_ACCOUNTS_2 TABLE REPL.ACCOUNTS CHECK CONFLICTS BY ROW TIMESTAMP COLUMN TSTAMP UPDATE BY SYSTEM ON EXCEPTION ROLLBACK WORK MASTER EASTDS ON "EASTCOAST" SUBSCRIBER WESTDS ON "WESTCOAST";競合解消でデータ・ストアを双方向にレプリケートした場合、各データ・ストアのレプリケート表は、同じCHECK CONFLICTS属性で設定されている必要があります。レプリケート表のCHECK CONFLICTS設定を無効化または変更する必要がある場合は、「競合検出の無効化」の説明に従ってALTER REPLICATION文を使用し、各レプリケート・データ・ストアに適用します。
タイムスタンプ比較が有効になっている場合は、次のように入力します。
CHECK CONFLICTS BY ROW TIMESTAMP COLUMN ColumnName UPDATE BY SYSTEMTimesTenでは、基礎となるオペレーティング・システムによって返される現在の時間を使用してタイムスタンプの値が自動的にメンテナンスされます。これがデフォルトの設定です。
UPDATE BY SYSTEMを指定すると、TimesTenは次の処理を実行します。
初期ロード時、タイムスタンプ列の値はNULLのままにしておく必要があります。また、行の挿入時または更新時に、アプリケーションでタイムスタンプ列に値を指定しないでください。
ttBulkCpまたはttMigrateユーティリティを使用してTimesTen表を保存した場合、保存された行にそれらの現在のタイムスタンプ値が保持されます。その後、表がTimesTenにコピーまたは移行された場合は、コピー・ファイルまたは移行ファイルが作成された時点でタイムスタンプ列に含まれていた値が保持されます。
表でタイムスタンプ比較が有効になっている場合は、次のように入力します。
CHECK CONFLICTS BY ROW TIMESTAMP COLUMN ColumnName UPDATE BY USERアプリケーションでタイムスタンプ値をメンテナンスする必要があります。アプリケーションで使用されるタイムスタンプ値は任意に設定できますが、時間値は小さくできません。ユーザーがタイムスタンプ列を明示的に設定または更新した場合、アプリケーション指定の値が現在の時間のかわりに使用されます。
レプリケーション・サイト間で表の同期をメンテナンスするには、TimesTen Data Managerでローカル・トランザクションが実行する更新に対してもタイムスタンプ比較を行います。更新された表に自動タイムスタンプ・メンテナンスが宣言されている場合、現在のシステム時間を超えるタイムスタンプを持つレコードへの更新は禁止されます。
通常、レプリケート・システムのクロックは、他のシステムに保存されているレコードのタイムスタンプより後のタイムスタンプがローカルで更新された同じレコードに指定されるように十分に同期されています。完全に同期させることは不可能ですが、レプリケーションでは、レコードのタイムスタンプが過去にさかのぼらないようにすることによって、レプリケート・システムの表を同期されたままにするための処理を行うことができます。
次のように指定してレポートをリクエストしたとします。
CHECK CONFLICTS BY ROW TIMESTAMP COLUMN ColumnName ... REPORT TO 'FileName'競合について記述しているレポート・ファイル(FileName )にエントリが追加されます。
障害が発生した各処理は、ヘッダーで始まるエントリの後に、競合している処理に固有の情報が続く構成でレポートにロギングされています。レポート内の各エントリは、多数の空白行で区切られています。
ヘッダーには次の情報が含まれます。
ヘッダーの書式は次のとおりです。
Conflict detected at <time> on <date> Datastore : <subscriber datastore> Transmitting name : <master datastore> Table : <username>.<tablename>例:
Conflict detected at 20:08:37 on 05-17-2004 Datastore : /tmp/subscriberds Transmitting name : MASTERDS Table : USER1.T1ヘッダーの後には、競合に固有の情報が続きます。データ値はASCII形式で表示されます。バイナリ・データは表示前に16進形式に変換され、浮動小数点値が適切な精度およびスケールで表示されます。
次の項では、各タイプの競合で生成されるレポートについて説明します。各例で、CREATE REPLICATION文のCHECK CONFLICTS句にON EXCEPTION ROLLBACK WORKオプションを指定して、競合しているトランザクションを強制終了します。
競合が原因でレプリケート対象のINSERTが失敗した場合、一意競合レコードが発行されます。
レポート・ファイルの一意競合レコードには、次の情報が含まれます。
一意競合レコードの書式は、次のとおりです。
Conflicting insert tuple timestamp : <timestamp in binary format> Existing tuple timestamp : <timestamp in binary format> The existing tuple : <<column value> [,<column value>. ..]> The conflicting tuple : <<column value> [,<column value> ...]> The key columns for the tuple: <<key column name> : <key column value>> Transaction containing this insert skipped Failed transaction: Insert into table <user>.<table> <<column value> [,<column value>...]> End of failed transaction例8.3に、主キー値2で識別される行に対する一意競合の出力を示します。SUBSCRIBERDSからレプリケートされた古い挿入がMASTERDS内の新しい挿入と競合しているため、レプリケート対象の挿入は破棄されます。
Conflict detected at 13:36:00 on 03-25-2002 Datastore : /tmp/masterds Transmitting name : SUBSCRIBERDS Table : REPL.TAB Conflicting insert tuple timestamp : 3C9F983D00031128 Existing tuple timestamp : 3C9F983E000251C0 The existing tuple : < 2, 2, 3C9F983E000251C0> The conflicting tuple : < 2, 100, 3C9F983D00031128> The key columns for the tuple: <COL1 : 2> Transaction containing this insert skipped Failed transaction: Insert into table REPL.TAB < 2, 100, 3C9F983D00031128> End of failed transaction
競合が原因でレプリケート対象のUPDATEが失敗した場合、更新競合レコードが発行されます。このレコードには次の情報がレポートされます。
更新競合レコードの書式は、次のとおりです。
Conflicting update tuple timestamp : <timestamp in binary format> Existing tuple timestamp : <timestamp in binary format> The existing tuple : <<column value> [,<column value>. ..]> The conflicting update tuple : TSTAMP :<timestamp> :<<column value> [,<column value>. ..]> The old values in the conflicting update: TSTAMP :<timestamp> :<<column value> [,<column value>. ..]> The key columns for the tuple: <<key column name> : <key column value>> Transaction containing this update skipped Failed transaction: Update table <user>.<table> with keys: <<key column name> : <key column value>> New tuple value: <TSTAMP :<timestamp> :<<column value> [,<column value>. ..]> End of failed transaction例8.4に、主キー値6で識別される行のCOL2値に対する更新競合の出力を示します。MASTERDSデータ・ストアからレプリケートされた古い更新がSUBSCRIBERDS内の新しい更新と競合しているため、レプリケート対象の更新は破棄されます。
Conflict detected at 15:03:18 on 03-25-2002 Datastore : /tmp/subscriberds Transmitting name : MASTERDS Table : REPL.TAB Conflicting update tuple timestamp : 3C9FACB6000612B0 Existing tuple timestamp : 3C9FACB600085CA0 The existing tuple : < 6, 99, 3C9FACB600085CA0> The conflicting update tuple : <TSTAMP :3C9FACB6000612B0, COL2 : 50> The old values in the conflicting update: <TSTAMP :3C9FAC85000E01F0, COL2 : 2> The key columns for the tuple: <COL1 : 6> Transaction containing this update skipped Failed transaction: Update table REPL.TAB with keys: <COL1 : 6> New tuple value: <TSTAMP :3C9FACB6000612B0, COL2 : 50> End of failed transaction
最近削除された行に対して更新を行おうとすると、削除/更新競合レコードが発行されます。このレコードには、次の情報がレポートされます。
失敗した更新との削除競合を示すレコードの書式は、次のとおりです。
Conflicting update tuple timestamp : <timestamp in binary format> The conflicting update tuple : TSTAMP :<timestamp> :<<column value> [,<column value>. ..]> This transaction skipped The tuple does not exist Transaction containing this update skipped Update table <user>.<table> with keys: <<key column name> : <key column value>> New tuple value: <TSTAMP :<timestamp> :<<column value> [,<column value>. ..]> End of failed transaction例8.5に、最近削除された行に対する更新で発生した削除/更新競合の出力を示します。更新する行がないため、SUBSCRIBERDSからの更新は破棄されます。
Conflict detected at 15:27:05 on 03-25-2002 Datastore : /tmp/masterds Transmitting name : SUBSCRIBERDS Table : REPL.TAB Conflicting update tuple timestamp : 3C9FB2460000AFC8 The conflicting update tuple : <TSTAMP :3C9FB2460000AFC8, COL2 : 99> The tuple does not exist Transaction containing this update skipped Failed transaction: Update table REPL.TAB with keys: <COL1 : 2> New tuple value: <TSTAMP :3C9FB2460000AFC8, COL2 : 99> End of failed transaction失敗した削除との更新競合を示すレコードの書式は、次のとおりです。
Conflicting binary delete tuple timestamp : <timestamp in binary format> Existing binary tuple timestamp : <timestamp in binary format> The existing tuple : <<column value> [,<column value>. ..]> The key columns for the tuple: <<key column name> : <key column value>> Transaction containing this delete skipped Failed transaction: Delete table <user>.<table> with keys: <<key column name> : <key column value>> End of failed transaction例8.6に、最近更新された行に対する削除で発生した削除/更新競合の出力を示します。削除より後に更新された行があるため、SUBSCRIBERDSからの削除は破棄されます。
Conflict detected at 15:27:20 on 03-25-2002 Datastore : /tmp/subscriberds Transmitting name : MASTERDS Table : REPL.TAB Conflicting binary delete tuple timestamp : 3C9FB258000708C8 Existing binary tuple timestamp : 3C9FB25800086858 The existing tuple : < 147, 99, 3C9FB25800086858> The key columns for the tuple: <A : 147> Transaction containing this delete skipped Failed transaction: Delete table REPL.TAB with keys: <A : 147>