21

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

4

1 に答える 1

31

を使用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)、次に操作を行う必要があります。操作が完了したら、カーソルを閉じてコミットします。

編集 一時的に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.

于 2012-11-06T09:58:11.590 に答える