INSERT オペレーションは新しいローを作成します。SQL Anywhere では、データ整合性を確保するために、挿入時に各種のロックを利用します。どの独立性レベルであっても実行している INSERT 文では、次の操作手順が発生します。
テーブルで共有スキーマ・ロックを保持していない場合は、取得します。
テーブルで書き込みを意図したテーブル・ロックを保持していない場合は、取得します。
新しいローを格納するために、ページでロックされていない位置を検索します。ロック競合を最小限に抑えるために、サーバは、削除された (しかしコミットしない) ローによって利用可能になった領域をただちに再利用しません。新しいローを確保するために、新しいページがテーブルに割り当てられることがあります。また、データベース・ファイルのサイズが増大することがあります。
新しいローに値を入れます。
ローを追加するテーブルに挿入ロックをかけます。挿入ロックは排他ロックであるため、一度挿入ロックをかけると、独立性レベル 3 の他のトランザクションは、幻ロックをかけて挿入をブロックすることができません。
新しいローに書き込みロックをかけます。書き込みロックが取得されると、挿入ロックが解放されます。
テーブルにローを挿入します。ここで、独立性レベル 3 の他のトランザクションは初めて新しいローの存在に気が付きます。ただし、すでに書き込みロックがかかっているため、これらのトランザクションはそのローの修正や削除はできません。
影響を受けるすべてのインデックスを更新し、必要に応じてユニークであることを確認します。プライマリ・キーの値はユニークである必要があります。他のカラムもユニークな値だけを含むように定義される場合があります。このようなカラムが存在する場合は、ユニーク性が検証されます。
テーブルが外部テーブルである場合は、プライマリ・テーブルの共有スキーマ・ロックを保持していなければ取得し、挿入される外部キー・カラムの値が NULL でない場合は、プライマリ・テーブルの一致するプライマリ・ローで読み込みロックを取得します。データベース・サーバは、挿入トランザクションで COMMIT が実行されたときにプライマリ・ローが存在していることを保証する必要があります。この確認は、プライマリ・ローの読み込みロックを取得して行います。読み込みロックをかけても他のトランザクションは自由にそのローを読むことができますが、削除や更新はできません。
対応するプライマリ・ローが存在しない場合は、参照整合性制約違反が発生します。
最後の手順の後、テーブルで定義された AFTER INSERT トリガが起動します。トリガ内の処理におけるロック動作は、アプリケーションの場合と同じです。トランザクションがコミット (すべての参照整合性制約が満たされる) またはロールバックされると、すべての長期間ロックが解放されます。
特定のカラムまたはカラムの組み合わせに設定される値のすべてをユニークにすることができます。ユーザがあえて作成しなくても、データベース・サーバがそのユニークなカラムに対するインデックスを作成し、それによって値のユニーク性を保証しています。
特に、プライマリ・キーの値はすべてユニークである必要があります。データベース・サーバは、すべてのテーブルのプライマリ・キーに対するインデックスを自動的に作成します。プライマリ・キーに対するインデックスを作成するようデータベース・サーバに要求しないでください。これをすると、重複するインデックスが作成されてしまいます。
外部キーは、通常別のテーブルにあるプライマリキーまたは一意性制約を参照します。そのプライマリ・キーが存在しない場合、対応する外部キーは「オーファン」と呼ばれます。SQL Anywhere は、データベースにオーファンがないかを自動的に確認します。このプロセスを「参照整合性の検証」と呼びます。データベース・サーバは、オーファン数をカウントし参照整合性を調べます。
データベース・サーバに対し、トランザクションの終了まで参照整合性の検証を遅延するように指示できます。このモードでは、外部キーを含む 1 つのローを挿入し、次にプライマリ・キーを持たないプライマリ・ローを挿入できます。この両方のオペレーションは同じトランザクションで実行する必要があります。
データベース・サーバがコミット時間まで参照整合性の検証を遅延するように要求するには、wait_for_commit オプションを On に設定します。デフォルトでは、このオプションは Off に設定されます。ON にするには、次のコマンドを実行します。
SET OPTION wait_for_commit = On; |
新しい外部キー値が挿入されるときにサーバが一致するプライマリ・ローを見つけられず、wait_for_commit が On の場合、サーバはオーファンとして挿入を許可します。孤立した外部ローの場合は、挿入時に次の手順が発生します。
サーバは、プライマリ・テーブルで共有スキーマ・ロックを保持していない場合は取得します。また、プライマリ・テーブルで書き込みを意図したロックを取得します。
サーバは、プライマリ・テーブルに代理ローを挿入します。実際のローはプライマリ・テーブルに挿入されません。ただし、サーバはロックをかけるためにそのローのユニークなロー識別子を作成し、この代理ローで書き込みロックを取得します。次に、サーバはプライマリ・テーブルのプライマリ・キー・インデックスに適切な値を挿入します。
トランザクションをコミットする前に、データベース・サーバはトランザクションが作成したオーファン数をチェックし参照整合性が維持されているかを調べます。各トランザクションの終了時に、この数は 0 になっていなければなりません。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |