デフォルトでは、多数のデータ構造がOracleにより暗黙的(自動的)にロックされます。ただし、デフォルトのロックをオーバーライドして、別のロックを有効にする場合は、行または表を特定して、そこにデータ・ロックを要求できます。明示的なロックにより、トランザクション中に表に対するアクセスを共有または制限したり、複数の表および複数の問合せの読取り一貫性を確保できます。
SELECT FOR UPDATE OF
文を使用すると、表の特定行を明示的にロックすることで、更新または削除が実行されるまで、その行が変更されないようにできます。ただし、Oracleでは、更新時または削除時には自動的に行レベルのロックが行われます。したがって、更新または削除の前にロックする場合にのみ、FOR UPDATE OF
句を使用してください。
LOCK TABLE
文を使用すると、表全体をロックできます。
UPDATE
文またはDELETE
文のCURRENT
OF
句で参照されるカーソルをDECLARE
する場合は、 FOR UPDATE OF句を使用すると行の排他的ロックを取得できます。SELECT FOR UPDATE OF
文では、更新または削除の対象となる行が識別され、アクティブ・セット内の各行がロックされます。(行はすべて、オープン時にロックされ、フェッチ時にはロックされません。)これは、ある行内の既存の値に基づいて更新処理を行う場合に便利です。更新前に、その行が他のユーザーにより変更されないようにする必要があります。
FOR UPDATE OF
句はオプションです。たとえば、次のようなコードがあるとします。
EXEC SQL DECLARE emp_cursor CURSOR FOR SELECT ENAME, JOB, SAL FROM EMP WHERE DEPTNO = 20 FOR UPDATE OF SAL;
ここでFOR UPDATE OF
句を削除すると、次のようにコードが単純になります。
EXEC SQL DECLARE emp_cursor CURSOR FOR SELECT ENAME, JOB, SAL FROM EMP WHERE DEPTNO = 20;
CURRENT OF
句では、必要に応じてFOR UPDATE句を追加するようにプリコンパイラに指示します。CURRENT OF
句を使用して、カーソルから最後にフェッチされた行を参照します。
LOCK TABLE
文を使用すると、指定したロック・モードで1つ以上の表をロックできます。たとえば、文はEMP表を行共有モードにロックします。行共有ロックでは、表への同時アクセスが可能です。他のユーザーが表全体をロックして排他使用することはできません。
EXEC SQL LOCK TABLE EMP IN ROW SHARE MODE NOWAIT;
ロック・モードによって、その表に設定できる他のロックが決定されます。たとえば、多くのユーザーが同時に1つの表に対して行共有ロックを取得できる一方、排他ロックを取得できるのは一度に1ユーザーのみです。あるユーザーが表を排他ロックしている間は、他のユーザーはその表内の行の挿入、更新または削除を行えません。ロック・モードの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。
オプションのキーワードNOWAITを指定すると、他のユーザーが表をロックしている場合は、その表の解放を待機しないようにOracleに対して指示できます。制御はただちにプログラムに戻されるため、プログラムではロックの取得を再度試みるまでの間に別の作業ができます。(SQLCA内のSQLCODEをチェックすると、表ロックが失敗したか確認できます。)NOWAIT
を省略すると、表が利用可能になるまで、Oracleは待機します。待機の時間制限は設定されていません。
表をロックしても、他のユーザーは表に対して問合せができますが、問合せを実行しても表ロックを取得できません。したがって、問合せが他の問合せや更新を妨げることはなく、更新が問合せを妨げることもありません。2つの異なるトランザクションで同じ行の更新が試みられる場合にのみ、一方のトランザクションが他方のトランザクションの完了まで待機の状態になります。表のロックは、トランザクションがコミットまたはロールバックを発行すると解除されます。