Подтвердить что ты не робот

Когда следует использовать "для обновления nowait" в курсорах?

В этом случае нам нужно использовать for update nowait в курсорах.

4b9b3361

Ответ 1

Использование for update nowait приведет к тому, что строки будут заняты и получит блокировку, пока не будет выполнен коммит или откат. Любой другой сеанс, который пытается получить блокировку, получит сообщение об ошибке Oracle, такое как ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired, вместо того, чтобы ждать разблокировки блокировки.

Сессии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 Предположим, что в строке 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 

Если я выполню тот же сценарий в сеансе 2, пока сценарий в сеансе 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;

Тогда я получаю ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.