Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SAP Sybase SQL Anywhere 16.0 » SQL Anywhere サーバ SQL の使用法 » トランザクションと独立性レベル » 独立性レベルのチュートリアル » チュートリアル:幻ローの知識

 

レッスン 1:幻ローの作成

Sales Manager がローを挿入し、Accountant が隣接するローを読み出すことで、幻ローを作成します。このアクションにより、新しいローが幻として表示されます。

前提条件

このレッスンでは、このチュートリアルの開始時に、権限のセクションで一覧されているロールと権限を持っていることを前提としています。 チュートリアル:幻ローの知識

 ♦ タスク
  1. 次の文を実行して、Sales Manager と Accountant のウィンドウにそれぞれ独立性レベル 2 を設定します。

    SET TEMPORARY OPTION isolation_level = 2;
  2. Accountant として次の文を実行し、すべての部署のリストを表示します。

    SELECT * FROM GROUPO.Departments
    ORDER BY DepartmentID;
    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
  3. Sales Manager は、主に外国市場を担当する新しい部署の設置を決めました。EmployeeID 129 の Philip Chin を新しい部署の責任者にします。Sales Manager として、次の文を実行し、新しい部署用のエントリを作成します。この新しいエントリは、Sales Manager のウィンドウのテーブル下部に新しいローとして表示されます。

    INSERT INTO GROUPO.Departments
       ( DepartmentID, DepartmentName, DepartmentHeadID )
       VALUES( 600, 'Foreign Sales', 129 );
       COMMIT;
  4. Sales Manager として次の文を実行し、すべての部署のリストを表示します。

    SELECT * FROM GROUPO.Departments
    ORDER BY DepartmentID;
    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
    600 Foreign Sales 129
  5. しかし Accountant は、新しい部署が作成されたことに気づきません。独立性レベル 2 で、データベースサーバはローを変更しないようにロックをかけますが、他のトランザクションが新しいローを挿入するのを防止するロックはかけていません。

    Accountant は SELECT 文を再実行した場合にだけ、新しいローを発見できます。Accountant として、SELECT 文を実行して、テーブルに追加された新しいローをもう一度表示します。

    SELECT * FROM GROUPO.Departments
    ORDER BY DepartmentID;
    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
    600 Foreign Sales 129

    新しく追加されたローは、「幻ロー」と呼ばれます。これは、Accountant の観点から見ると、このローがどこからともなく出現した幻のように映るためです。Accountant は独立性レベル 2 で接続されます。このレベルでは、サーバは使用中のローにだけロックをかけます。他のローにはロックがかけられないため、Sales Manager が新しいローを挿入するのを妨げるものはありません。

  6. Accountant は今後そうしたことが起こらないように、現在のトランザクションの独立性レベルを 3 に上げることにします。次の文を Accountant として実行します。

    SET TEMPORARY OPTION isolation_level = 3;
    SELECT * FROM GROUPO.Departments
    ORDER BY DepartmentID;
  7. Sales Manager は、大企業に対して営業活動を行う新しい部署を追加したいと考えています。Sales Manager として、次の文を実行します。

    INSERT INTO GROUPO.Departments
     ( DepartmentID, DepartmentName, DepartmentHeadID )
       VALUES( 700, 'Major Account Sales', 902 );

    Accountant のロックが文をブロックするため、Sales Manager のウィンドウは実行中に一時停止します。ツールバーで、[停止] をクリックして、このエントリを中止します。

    Accountant が独立性レベルを 3 に上げ、Departments テーブルのすべてのローを再度選択した場合、データベースサーバはテーブルの各ローに対挿入ロックを設定し、新しいローの挿入を防止するためにテーブルの最後にもう 1 つ幻ロックを設定します。Sales Manager がテーブルの最後に新しいローを挿入しようとすると、その文はこの最後のロックによってブロックされます。

    Sales Manager は独立性レベル 2 で接続されているにもかかわらず、Sales Manager の文はブロックされました。データベースサーバは独立性レベルと各トランザクション文の要求に応じ、読み込みロックと同様に幻ロックを設定します。一度対挿入ロックが設定されると、このロックは同時に実行される他のすべてのトランザクションに適用されます。

  8. SQL Anywhere サンプルデータベースが変更されないようにするため、Major Account Sales 部署のローを挿入する未完了トランザクションをロールバックし、2 つ目のトランザクションを使用して Foreign Sales 部署を削除してください。

    1. Accountant として、次の文を実行して独立性レベルを引き下げ、Sales Manager がデータベースに対する変更を取り消すことができるようにします。

      SET TEMPORARY OPTION isolation_level=3;
    2. Sales Manager として、次の文を実行して現在のトランザクションをロールバックし、以前挿入されたローを削除し、この操作をコミットします。

      ROLLBACK;
      DELETE FROM GROUPO.Departments
      WHERE DepartmentID = 600;
      COMMIT;

結果

Accountant は、SELECT 文が実行されるたびに異なる結果を受け取ります。したがって、スナップショット独立性レベル 3 を有効にして、幻ローを防ぎます。Accountant がデータベースを変更すると、Sales Manager はデータベースを変更できなくなります。

 参照