プライマリ・コンテンツに移動
Oracle® Database Oracleプリコンパイラのためのプログラマーズ・ガイド
12c リリース1 (12.1)
B71398-03
目次へ移動
目次
索引へ移動
索引

前
次

デフォルト・ロックのオーバーライドについて

デフォルトでは、多数のデータ構造がOracleにより暗黙的(自動的)にロックされます。ただし、デフォルトのロックをオーバーライドして、別のロックを有効にする場合は、行または表を特定して、そこにデータ・ロックを要求できます。明示的なロックにより、トランザクション中に表に対するアクセスを共有または制限したり、複数の表および複数の問合せの読取り一貫性を確保できます。

SELECT FOR UPDATE OF文を使用すると、表の特定行を明示的にロックすることで、更新または削除が実行されるまで、その行が変更されないようにできます。ただし、Oracleでは、更新時または削除時には自動的に行レベルのロックが行われます。したがって、更新または削除のにロックする場合にのみ、FOR UPDATE OF句を使用してください。

LOCK TABLE文を使用すると、表全体をロックできます。

FOR UPDATE OF句の使用について

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句を使用して、カーソルから最後にフェッチされた行を参照します。

制限

FOR UPDATE OF句を使用すると、複数の表を参照できません。また、明示的なFOR UPDATE OFまたは暗黙的FOR UPDATEでは、行の排他ロックが取得されます。行ロックが解除されるのは、コミット時またはロールバック時です(セーブポイントまでロールバックする場合は、解除されません)。コミット後にFOR UPDATEカーソルからフェッチしようとすると、次のエラーが発生します。

ORA-01002: fetch out of sequence

LOCK TABLE文の使用について

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つの異なるトランザクションで同じ行の更新が試みられる場合にのみ、一方のトランザクションが他方のトランザクションの完了まで待機の状態になります。表のロックは、トランザクションがコミットまたはロールバックを発行すると解除されます。