発生する可能性のあるトランザクションの非一貫性の例

この例では、2つの増分自動リフレッシュ読取り専用キャッシュ・グループを作成する方法を示します。

次の例では、employee表およびdepartment表を使用しますが、ここでdepartment表のdepartment idは外部キーで、employee表のdepartment idを示しています。

次の例では、2つの増分自動リフレッシュ読取り専用キャッシュ・グループを作成しますが、それぞれのキャッシュ・グループは独自のキャッシュ・グループ内にあります。大規模なトランザクションの前にttCacheAutorefreshXactLimitにより自動リフレッシュ・トランザクション制限の設定を有効にし、トランザクションの完了後に設定を無効にします。

  1. 大規模なトランザクションを開始する前に、ttCacheAutorefreshXactLimitを起動して、間隔の値およびその間隔で自動的にコミットする処理数を設定します。次の例では、間隔が2秒に設定されているすべての増分自動リフレッシュ読取り専用キャッシュ・グループに対して、処理数を3 (例を簡単にするために意図的に小さな値にしています)に設定しています。

    CALL ttCacheAutorefreshXactLimit('2000', '3');
    < 2000, 3 >
    1 row found.
  2. 間隔を2秒に設定して、増分自動リフレッシュ読取り専用キャッシュ・グループを作成します。この例では、2つの静的(動的ではない)読取り専用キャッシュ・グループを作成しますが、それぞれのキャッシュ・グループに表が1つ含まれています。

    CREATE READONLY CACHE GROUP cgDepts AUTOREFRESH MODE INCREMENTAL 
     INTERVAL 2 SECONDS 
    FROM departments
        ( department_id    NUMBER(4) PRIMARY KEY
        , department_name  VARCHAR2(30) NOT NULL
        , manager_id       NUMBER(6)
        , location_id      NUMBER(4)
        );
     
    CREATE READONLY CACHE GROUP cgEmpls AUTOREFRESH MODE INCREMENTAL 
     INTERVAL 2 SECONDS 
    FROM employees
        ( employee_id    NUMBER(6) PRIMARY KEY
        , first_name     VARCHAR2(20)
        , last_name      VARCHAR2(25) NOT NULL
        , email          VARCHAR2(25) NOT NULL UNIQUE
        , phone_number   VARCHAR2(20)
        , hire_date      DATE NOT NULL
        , job_id         VARCHAR2(10) NOT NULL
        , salary         NUMBER(8,2)
        , commission_pct NUMBER(2,2)
        , manager_id     NUMBER(6)
        , department_id  NUMBER(4)
        );
  3. 自動リフレッシュを使用した両方のキャッシュ・グループのLOAD CACHE GROUP文を実行します。

    LOAD CACHE GROUP cgDepts COMMIT EVERY 256 ROWS;
    27 cache instances affected.
     
    LOAD CACHE GROUP cgEmpls COMMIT EVERY 256 ROWS;
    107 cache instances affected.

employees表で示されているように、自動リフレッシュ中は表内に非一貫性が発生する場合があります。

  1. TimesTenで、すべての従業員の給与の最大値と最小値を選択します。

    SELECT MIN(salary), MAX(salary) FROM employees;
    < 2100, 24000 >
    1 row found.
  2. Oracle Databaseで、全員の給与に100,000を追加します。

    UPDATE employees SET salary = salary + 100000;
    107 rows updated.
  3. TimesTenで、再度SELECTを実行すると(自動リフレッシュ・トランザクションは3レコードごとにコミットされています)、給与の最大値は更新されていますが、最小値は元の値のままです。

    SELECT MIN(salary), MAX(salary) FROM employees;
    < 2100, 124000 >
    1 row found.
  4. ただし、自動リフレッシュが完了すると、トランザクションの一貫性が確保されます。この例では、自動リフレッシュ・プロセスが完了すると、すべての従業員の給与が100,000だけ増加しています。

    SELECT MIN(salary), MAX(salary) FROM employees;
    < 102100, 124000 >
    1 row found.
  5. 大規模なトランザクションが完了したため、間隔が2秒に設定されている自動リフレッシュのキャッシュ・グループに対するトランザクション制限の設定を無効にします。

    call ttCacheAutorefreshXactLimit('2000', 'OFF');

自動リフレッシュ・プロセスの進行中にSQL文を実行すると、キャッシュ・グループ間でトランザクションの非一貫性が発生する可能性があります。次の例では、cgDepts自動リフレッシュ・グループ内のemployees表およびdepartment表に対してSELECT文を実行します。この例では、TimesTenで外部キーが指定されておらず、自動リフレッシュ・プロセスが複数のトランザクションに適用されているため、departmentの更新の前にemployee表の更新が挿入される場合があります。

さらに、キャッシュ・グループ内の両方の表に対するすべての更新は、自動リフレッシュ・サイクルが完了するまでは適用されません。次の例では、自動リフレッシュ・プロセスが完了する前にSELECT文が実行されています。このように、結果には必要なデータがすべて表示されているわけではなく、部門名や複数の従業員(法務部1000の弁護士の一部)が欠落しています。

SELECT e.department_id, d.DEPARTMENT_NAME, e.FIRST_NAME, e.LAST_NAME  
       FROM employees e, departments d         
       WHERE e.DEPARTMENT_ID  = d.DEPARTMENT_ID (+) 
       AND e.department_id >= 1000 ORDER BY 1,2,3,4;
< 1000, Legal, Alec, Dunkle >
< 1000, Legal, Barry, Strong >
< 1000, Legal, Leigh, Harrison >
3 rows found.

ただし、自動リフレッシュ・プロセスが完了すると、トランザクションの一貫性が確保されます。次の例では、自動リフレッシュの完了後に同じSELECT文が実行されています。この場合、部門情報や新しいすべての弁護士などの必要なデータがすべて更新されています。

SELECT e.department_id, d.DEPARTMENT_NAME, e.FIRST_NAME, e.LAST_NAME  
       FROM employees e, departments d         
       WHERE e.DEPARTMENT_ID  = d.DEPARTMENT_ID (+) 
       AND e.department_id >= 1000 ORDER BY 1,2,3,4;
< 1000, Legal, Alec, Dunkle >
< 1000, Legal, Barry, Strong >
< 1000, Legal, Leigh, Harrison >
< 1000, Legal, John, Crust >
< 1000, Legal, Robert, Wright >
< 1000, Legal, Robert, Smith >
6 rows found.

複数の表を持つ自動リフレッシュを使用したキャッシュ・グループの場合も、自動リフレッシュ・プロセスの進行中にSQL文を実行すると、トランザクションの非一貫性が発生することがあります。

  1. ttCacheAutorefreshXactLimit組込みプロシージャにより、2秒間隔の自動リフレッシュを使用した増分キャッシュ・グループに対してトランザクション制限の設定を開始し、employeesおよびdepartmentsの2つの表を持つ単一の自動リフレッシュ・キャッシュ・グループを作成します。
    CALL ttCacheAutorefreshXactLimit('2000', '3');
    < 2000, 3 >
    1 row found.
     
    CREATE READONLY CACHE GROUP cgDeptEmpls AUTOREFRESH MODE INCREMENTAL
     INTERVAL 2 SECONDS 
    FROM departments
         ( department_id    NUMBER(4) PRIMARY KEY
         , department_name  VARCHAR2(30) NOT NULL
         , manager_id       NUMBER(6)
         , location_id      NUMBER(4)
         )
       , employees
         ( employee_id    NUMBER(6) PRIMARY KEY
         , first_name     VARCHAR2(20)
         , last_name      VARCHAR2(25) NOT NULL
         , email          VARCHAR2(25) NOT NULL UNIQUE
         , phone_number   VARCHAR2(20)
         , hire_date      DATE NOT NULL
         , job_id         VARCHAR2(10) NOT NULL
         , salary         NUMBER(8,2)
         , commission_pct NUMBER(2,2)
         , manager_id     NUMBER(6)
         , department_id  NUMBER(4)
         , foreign key(department_id) references departments(department_id)
         );
  2. キャッシュ・グループの手動によるロード
    LOAD CACHE GROUP cgDeptEmpls COMMIT EVERY 256 ROWS;
    27 cache instances affected.
  3. TimesTenでSELECT文を実行し、法務部のデータをすべてアップロードします。
    SELECT e.department_id, d.department_name, count(*)
           FROM employees e, departments d         
           WHERE e.department_id  = d.department_id (+) 
           GROUP BY e.department_id, d.department_name
           ORDER BY 1 desc;
    < 110, Accounting, 2 >
    < 100, Finance, 6 >
    < 90, Executive, 3 >
    < 80, Sales, 34 >
    < 70, Public Relations, 1 >
    < 60, IT, 5 >
    < 50, Shipping, 45 >
    < 40, Human Resources, 1 >
    < 30, Purchasing, 6 >
    < 20, Marketing, 2 >
    < 10, Administration, 1 >
    11 rows found.
  4. Oracleでemployeeおよびdepartmentの両方の表に、6人の新しい弁護士が所属する新しい法務部(番号1000)を挿入します。
  5. 自動リフレッシュ・プロセス時にTimesTenでSELECT文を実行すると、部門1000の2人の弁護士に関するデータのみがTimesTenにアップロードされます。
    SELECT e.department_id, d.department_name, count(*)
           FROM employees e, departments d         
           WHERE e.department_id  = d.department_id (+) 
           GROUP BY e.department_id, d.department_name
           ORDER BY 1 desc;
    < 1000, Legal, 2 >
    < 110, Accounting, 2 >
    < 100, Finance, 6 >
    < 90, Executive, 3 >
    < 80, Sales, 34 >
    < 70, Public Relations, 1 >
    < 60, IT, 5 >
    < 50, Shipping, 45 >
    < 40, Human Resources, 1 >
    < 30, Purchasing, 6 >
    < 20, Marketing, 2 >
    < 10, Administration, 1 >
    12 rows found.
  6. ただし、自動リフレッシュ・プロセスが完了すると、法務部に所属する6人の従業員(弁護士)すべてのデータがTimesTenにアップロードされます。これにより、現時点においてトランザクションの一貫性が確保されます。
    SELECT e.department_id, d.department_name, COUNT(*)
           FROM employees e, departments d         
           WHERE e.department_id  = d.department_id (+) 
           GROUP BY e.department_id, d.department_name
           ORDER BY 1 desc;
    < 1000, Legal, 6 >
    < 110, Accounting, 2 >
    < 100, Finance, 6 >
    < 90, Executive, 3 >
    < 80, Sales, 34 >
    < 70, Public Relations, 1 >
    < 60, IT, 5 >
    < 50, Shipping, 45 >
    < 40, Human Resources, 1 >
    < 30, Purchasing, 6 >
    < 20, Marketing, 2 >
    < 10, Administration, 1 >
    12 rows found.
  7. 大規模なトランザクションが完了したため、間隔が2秒に設定されている自動リフレッシュのキャッシュ・グループに対するトランザクション制限の設定を無効にします
    call ttCacheAutorefreshXactLimit('2000', 'OFF');