アプリケーション開発の手引き


保管点によるトランザクションの制御

保管点とは、データベース要求が失敗する際に DBMS によって行われた作業を取り消すメカニズムを表します。保管点はアトミックではないデータベース要求がアトミックに振る舞うようにします。実行時にエラーが発生する場合、保管点を使って保管点が開始された時点から保管点ロールバックが要求された時点までの、トランザクションによる変更を取り消すことができます。

保管点は複合 SQL ステートメントに類似しています。これにより、いくつもの SQL ステートメントを単一の実行可能なブロックにグループ化することが可能になります。そのためには、このブロックの最初のサブステートメントが実行される前に、保管点ブロックを開始するための保管点要求が必要です。サブステートメントのいずれかがエラーを起こす場合には、そのサブステートメントだけがロールバックされます。この方法では、複合 SQL ステートメントを使用するよりも細分性を図ることができます。複合 SQL ステートメントでは、 1 つのエラーによってブロック全体が終了して、複合 SQL ステートメント全体がロールバックされます。ステートメントの保管点ブロックの最後で保管点を解放するか、保管点へロールバックすることができます。

次の SQL ステートメントで保管点を作成および制御することができます。

SAVEPOINT
保管点を設定するには、 SAVEPOINT SQL ステートメントを発行します。コードをより鮮明なものにするには、保管点のために分かりやすい名前を選ぶことができます。以下はその例です。

SAVEPOINT savepoint1 ON ROLLBACK RETAIN CURSORS

RELEASE SAVEPOINT
保管点を解放するには、 RELEASE SAVEPOINT SQL ステートメントを発行します。 RELEASE SAVEPOINT SQL ステートメントを使用して保管点を明示的に解放しない場合には、トランザクションの終わりで解放されます。以下はその例です。

RELEASE SAVEPOINT savepoint1

ROLLBACK TO SAVEPOINT
保管点へロールバックするには、 ROLLBACK TO SAVEPOINT という SQL ステートメントを発行します。以下はその例です。

ROLLBACK TO SAVEPOINT

SAVEPOINT、RELEASE SAVEPOINT、および ROLLBACK TO SAVEPOINT ステートメントの完全な構文については、 SQL 解説書 を参照してください。

保管点の制約事項

DB2 ユニバーサル・データベースでは、アプリケーションでの保管点の使用に関して次のような制約があります。

アトミック複合 SQL
DB2 では、アトミック複合 SQL での保管点は使用できません。保管点内ではアトミック複合 SQL を使用することはできません。

ネストされた保管点
DB2 では、別の保管点での保管点の使用をサポートしておりません。

トリガー
DB2 では、トリガーでの保管点の使用をサポートしておりません。

トランザクション内での保管点の数
DB2 では、トランザクション内で必要なだけ保管点を設定および使用することができます。

SET INTEGRITY ステートメント
保管点内では、 DB2 は SET INTEGRITY ステートメントを DDL ステートメントとして扱います。保管点での DDL の使用の詳細については、保管点およびデータ定義言語 (DDL) を参照してください。

保管点およびデータ定義言語 (DDL)

DB2 は保管点内に DDL ステートメントを組み込むことを可能にします。 DDL ステートメントを実行する保管点をアプリケーションが正常に解放すると、そのアプリケーションは DDL によって作成された SQL オブジェクトを継続的に使用することができます。ただし、DDL ステートメントを実行する保管点に対してアプリケーションが ROLLBACK TO SAVEPOINT ステートメントを発行すると、DB2 はこれらの DDL ステートメントの効力に依存するカーソルをすべて無効とマーク付けします。

次の例では、アプリケーションは ROLLBACK TO SAVEPOINT ステートメントを発行した後に、以前に開かれた 3 つのカーソルからフェッチすることを試みます。

   SAVEPOINT savepoint_name;
      PREPARE s1 FROM 'sELECT FROM t1';
      --issue DDL statement for t1
         ALTER TABLE t1 ADD COLUMN...
      PREPARE s2 FROM 'sELECT FROM t2';
      --issue DDL statement for t3
         ALTER TABLE t3 ADD COLUMN...
      PREPARE s3 FROM 'sELECT FROM t3';
      OPEN c1 USING s1;
      OPEN c2 USING s2;
      OPEN c3 USING s3;
   ROLLBACK TO SAVEPOINT
   FETCH c1; --invalid (SQLCODE -910)
   FETCH c2; --successful
   FETCH c3; --invalid (SQLCODE -910)

ROLLBACK TO SAVEPOINT ステートメントでは、 DB2 は "c1" および "c3" カーソルを無効としてマーク付けします。なぜなら、それらのカーソルが依存していた SQL オブジェクトが保管点内の DDL ステートメントによって操作されたからです。しかし、この例の "c2" カーソルを使用した FETCH は、 ROLLBACK TO SAVEPOINT ステートメントの後でも正常に実行されます。

無効なカーソルをクローズするには、 CLOSE ステートメントを発行します。無効なカーソルに対して FETCH を発行すると、 DB2 によって SQLCODE -910 が戻されます。無効なカーソルに対して OPEN ステートメントを発行すると、 DB2 によって SQLCODE -502 が戻されます。無効なカーソルに対して UPDATE または DELETE WHERE CURRENT OF ステートメントを発行すると、DB2 によって SQLCODE -910 が戻されます。

保管点内では、 DB2 は NOT LOGGED INITIALLY 特性を持つ表と一時表を次のように扱います。

NOT LOGGED INITIALLY 表
保管点内では、 NOT LOGGED INITIALLY 特性付きの表を作成したり、 NOT LOGGED INITIALLY を持つように表を変更することができます。しかし、これらの保管点では、 DB2 は ROLLBACK TO SAVEPOINT ステートメントを ROLLBACK WORK ステートメントとして扱い、トランザクション全体をロールバックします。

保管点内での DECLARE TEMPORARY TABLE
保管点内で一時表が宣言されると、 ROLLBACK TO SAVEPOINT ステートメントによって一時表が除去されます。

保管点外での DECLARE TEMPORARY TABLE
保管点外で一時表が宣言されると、 ROLLBACK TO SAVEPOINT ステートメントは一時表を除去しません。

保管点およびバッファー化挿入

DB2 アプリケーションのパフォーマンスを向上させるには、 INSERT BUF オプションを使用してバインドを行うことによって、アプリケーションでバッファー化挿入を使用できます。アプリケーションがバッファー化挿入および保管点の両方を利用する場合、 DB2 は SAVEPOINT、RELEASE SAVEPOINT、 OR ROLLBACK TO SAVEPOINT ステートメントを実行する前にバッファーをフラッシュします。

アプリケーション内でバッファー化挿入を使用する方法についての詳細は、 バッファー化挿入の使用を参照してください。アプリケーション・プリコンパイルおよびバインドする方法についての詳細は、 コマンド解説書 を参照してください。

カーソル・ブロック化付きの保管点の使用

アプリケーションが保管点を使用する場合、 BLOCKING NO というプリコンパイル・オプションを指定することにより、プリコンパイルまたはバインドを行うときにカーソル・ブロックを回避することを考慮してください。カーソルをブロック化すると、複数の行が事前に取り出されるのでアプリケーションのパフォーマンスは向上しますが、保管点およびブロック化カーソルを使用するアプリケーションによって戻されたデータは、データベースにコミットされたデータを反映しない場合があります。

BLOCKING NO を使用してアプリケーションをプリコンパイルしないで、 ROLLBACK TO SAVEPOINT が発生した後に FETCH ステートメントを発行する場合には、FETCH ステートメントは削除されたデータを取り出すかもしれません。たとえば、次のような SQL を含んだアプリケーションが BLOCKING NO オプションなしでプリコンパイルされたとします。

   CREATE TABLE t1(c1 INTEGER);
   DECLARE CURSOR c1 AS 'sELECT c1 FROM t1 ORDER BY c1';
   INSERT INTO t1 VALUES (1);
   SAVEPOINT showFetchDelete;
      INSERT INTO t1 VALUES (2);
      INSERT INTO t1 VALUES (3);
      OPEN CURSOR c1;
      FETCH c1; --get first value and cursor block
      ALTER TABLE t1... --add constraint
   ROLLBACK TO SAVEPOINT;
   FETCH c1; --retrieves second value from cursor block

アプリケーションが "t1" 表に対して最初の FETCH を発行すると、 DB2 サーバーは列値 (1、2、および 3) のブロックをクライアント・アプリケーションに送ります。これらの列値はクライアントによってローカルで保管されます。アプリケーションが ROLLBACK TO SAVEPOINT SQL ステートメントを発行すると、列値 '2' および '3' が表から削除されます。 ROLLBACK TO SAVEPOINT ステートメント後は、表で次の FETCH が行われると、表にその値がないとしても、列値 '2' が戻されます。アプリケーションはカーソル・ブロック化オプションを利用してパフォーマンスを向上させ、ローカルに保管したデータにアクセスするために、この値を受け取ります。

アプリケーション・プリコンパイルおよびバインドの方法についての詳細は、 コマンド解説書 を参照してください。

保管点および XA に準拠したトランザクション・マネージャー

XA に準拠するトランザクション・マネージャーが XA_END 要求を発行する際にアプリケーションでアクティブな保管点が存在する場合には、 DB2 は RELEASE SAVEPOINT ステートメントを発行します。


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]