for update nowait
その場合、カーソルで使用する必要がありますか。
1 に答える
を使用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.