web-dev-qa-db-ja.com

カーソルで 'for update nowait'を使用する必要があるのはいつですか?

その場合、カーソルでfor update nowaitを使用する必要があります。

14
user1

for update nowaitを使用すると、行がビジーになり、コミットまたはロールバックが実行されるまでロックを取得します。ロックを取得しようとする他のセッションは、ロックの解放を待機する代わりに、ORA-00054: resource busy and acquire with NOWAIT specified or timeout expiredなどのOracleエラーメッセージを取得します。

セッション1:

CURSOR abc_cur 
IS 
select * from dept where deptno =10 for update nowait;

ここでは、カーソルが閉じられるか、コミット/ロールバックが実行されるまで行がロックされます。一方、セッション2の別のユーザーが同じレコードにアクセスしようとすると、次のようにエラーがスローされます。

セッション2:

select * from dept where deptno =10 for update nowait;

このユーザーは、最初のセッションでロックされた同じレコードを更新または削除することさえできません。

ERROR at line 1:
`ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired`

使用法:特定のレコードセットに対して何らかの操作を行いたい場合、別のセッションの別のユーザーにデータを上書きさせたくない場合は、最初にレコードをロックする必要があります(for update nowait)その後、操作を行います。操作が完了したら、カーソルを閉じてコミットします。

[〜#〜] edit [〜#〜] tempに10行あり、セッション1で次のスクリプトを実行するとします。

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

セッション2では、セッション1のスクリプトがまだ実行されている間に次を実行します

select * from temp;

10 rows found 

セッション1のスクリプトがまだ実行中に、セッション2で同じスクリプトを実行した場合

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

次に、ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.を取得します

21
Gaurav Soni