W takim przypadku musimy użyć for update nowait
w kursory.Kiedy należy używać "dla aktualizacji nowait" w kursory?
Odpowiedz
Użycie for update nowait
spowoduje, że wiersze będą zajęte i uzyskają blokadę, dopóki nie zostanie wykonane zatwierdzenie lub wycofanie. Każda inna sesja, która próbuje uzyskać blokadę, otrzyma komunikat o błędzie Oracle, taki jak ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release
.
Session1:
CURSOR abc_cur
IS
select * from dept where deptno =10 for update nowait;
Oto wiersze są zamknięte aż kursor jest zamknięty lub commit/rollback zostanie wykonany. Jeżeli w międzyczasie, inny użytkownik z sesji 2 próbuje uzyskać dostęp do tych samych zapisów, wówczas będzie to wygeneruje błąd, jak pokazano poniżej:
Session2:
select * from dept where deptno =10 for update nowait;
Ten użytkownik nie może nawet zaktualizować lub usunąć te same rekordy które zostały zablokowane przez pierwszą sesję.
ERROR at line 1:
`ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired`
Zastosowanie: Teraz, jeśli chcesz zrobić niektóre manipulacji na niektórych zestawów rekordów i nie chcesz innego użytkownika z innej sesji przesłonić swoje dane musisz najpierw zablokować rekordy (używając for update nowait
), a następnie wykonaj swoją manipulację. Po zakończeniu manipulacji zamknij kursor i zatwierdz.
EDIT Załóżmy w moim sesji 1 Mam wykonany następujący skrypt:
declare
cursor abc is select * from temp ;
temp abc%rowtype;
begin
open abc;
end;
teraz w sesji 2 I wykonywany
select * from temp ;
0 rows found
Gdybym ponownie wykonać ten sam skrypt
declare
cursor abc is select * from temp ;
temp abc%rowtype;
begin
open abc;
end;
Otrzymuję ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.
Więc jeśli nie używam czekania, nie mogę nawet pobrać (SELECT) tego samego wiersza z innej sesji, czy mam rację? – user1
Jeśli chcę pobrać, ale nie zaktualizować tego samego wiersza z innej sesji, w jaki sposób powinienem obsłużyć? – user1
@ użytkownik1: tak, możesz wybrać te same wiersze z drugiej sesji, ale nie możesz zablokować tych samych wierszy, jeśli zostało to zablokowane przez inną sesję. Możesz pobrać wiersze z innej sesji. –