データベースサーバーは次の手順を使用して特定のレコードに含まれる情報を修正します。挿入時と同様に、独立性レベルに関係なくすべてのトランザクションで次の操作手順が発生します。
テーブルで共有スキーマロックを保持していない場合は、取得します。
更新される各テーブルで書き込みを意図したテーブルロックを保持していない場合は、取得します。
更新されるテーブルごとに、テーブルにトリガーがある場合は、必要に応じて OLD 値と NEW 値のテンポラリテーブルを作成します。
更新の候補となるローを識別します。ローがスキャンされている間は、ローはロックされます。
独立性レベル 2 と 3 ではデフォルトのロック動作とは異なる次のような違いが発生します。読み込みロックではなく書き込みを意図したローレベルのロックが取得されます。また、書き込みを意図したロックは、更新の候補としては最終的には拒否されたローで取得される場合があります。
手順 2.a で識別された候補となる各ローは、残りのシーケンスに従います。
影響を受けるローに書き込みロックをかけます。
UPDATE 文により、影響を受けるそれぞれのカラムの値を更新します。
インデックス付きの値を変更した場合は、新しいインデックスエントリを追加します。ローの元のインデックスエントリは残りますが、削除済みのマークが付けられます。短期間の挿入ロックが保持されている間に、新しい値の新しいインデックスエントリが挿入されます。サーバーは、必要に応じてインデックスのユニーク性を検証します。
一意性違反が発生した場合は、ローの古い値と新しい値を格納するためにテンポラリ「保持」テーブルが作成されます。古い値と新しい値は保持テーブルにコピーされ、ベーステーブルのローは削除されます。DELETE トリガーは起動されません。ローごとの処理が終わるまで、手順 7 ~ 9 は行いません。
ローの外部キー値が変更された場合、プライマリテーブルで共有スキーマロックを取得し、新しい外部キー値を挿入する手順に従います。
同様に、必要に応じて wait_for_commit の手順に従います。
テーブルが参照整合性関係においてプライマリテーブルであり、かつ関係の UPDATE アクションが RESTRICT でない場合、外部テーブル (間) で共有スキーマロックを、各外部テーブルで書き込みを意図したテーブルロックをそれぞれ取得することで、外部テーブル内で影響のあるローを特定し、次に影響のあるすべてのローで書き込みロックを取得して、必要に応じてそれぞれのローを修正します。このプロセスは、参照整合性制約のネストした階層でカスケードされることがあります。
必要に応じて AFTER ROW トリガーを起動します。
保持テンポラリテーブルが必要だった場合には、最後の手順の後で、保持テンポラリテーブル内の各ローはベーステーブルに挿入されます (ただし、INSERT トリガーは起動されません)。ローの挿入が成功した場合は、上記の手順 7 ~ 9 が実行され、古いロー値と新しいロー値は OLD および NEW テンポラリテーブルにコピーされて、AFTER STATEMENT UPDATE トリガーによって、変更されたすべてのローが正しく処理されます。保持されたローがすべて処理された後、AFTER STATEMENT UPDATE トリガーが順番に起動されます。COMMIT の実行時、サーバーはこのトランザクションで生成されたオーファンの数が 0 であることを確認することで参照整合性を検証し、次にすべてのロックを解放します。
カラムの値を変更するために、多くの操作が必要になることがあります。データベースサーバーが実行する作業量は、修正するカラムがプライマリキーまたは外部キーの一部でない場合は大幅に少なくなります。カラムをユニークと宣言したために、変更する値が明示的または暗黙的にインデックスに含まれていない場合も作業量は少なくて済みます。
UPDATE オペレーション中に参照整合性を確認するオペレーションは、INSERT 中に確認する場合よりも複雑になります。実際、プライマリキーの値を変更すると、オーファンが作成されることがあります。置換値を挿入すると、データベースサーバーはもう一度オーファンをチェックしなければなりません。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |