У меня есть процедура ниже, которая перебирает курсор, выполняет некоторую логику. Я поставил FOR UPDATE NOWAIT на курсор, чтобы заблокировать мой набор записей на случай, если кто-то из другого сеанса захочет обновить тот же набор.
Но может быть сценарий, когда записи, которые я выбрал в своем курсоре, также кем-то заблокированы, и в этом случае я хочу просто зарегистрировать заблокированную запись в таблице журнала и перейти к следующей записи в цикле.
PROCEDURE test(p_id IN NUMBER)
IS
CURSOR cur_test IS
SELECT emp_id,
emp_name
FROM
EMP
FOR UPDATE NOWAIT;
row_locked EXCEPTION;
PRAGMA EXCEPTION_INIT(row_locked, -54);
BEGIN
FOR r_cur_test IN cur_test
LOOP
BEGIN
--do something
EXCEPTION
WHEN row_locked THEN
--log locked record in log table
log_lock('Record is locked');
COMMIT;
END;
END LOOP;
--call log function to log a successful run
COMMIT;
EXCEPTION
WHEN OTHERS THEN
--Unsuccessful completion of the run.Trap all unhandled exceptions.
--log error in error table
log_lock('Process exited with error');
ROLLBACK;
END;
для тестирования я открываю сеанс 1 и выполняю
select * from EMP FOR UPDATE NOWAIT
и в сеансе 2 я выполнил
begin
test(1);
end;
он всегда попадал в исключение OTHERS, в результате чего процедура просто завершалась, не продолжая зацикливаться на курсоре.
Кто-нибудь может дать мне совет? Большое спасибо
SQLERRM
и/илиRAISE
, иначе бессмысленно записывать факт возникновения ошибки. - person Boneist   schedule 28.11.2016