Есть ли альтернатива пропустить заблокирован для обновления в оракуле - PullRequest
0 голосов
/ 10 января 2019

У меня есть 5 строк в таблице. И некоторые строки заблокированы в некоторых сеансах.
Я не хочу генерировать никаких ошибок, просто хочу подождать, пока какая-либо строка не станет свободной для дальнейшей обработки

Я устал от Nowait и пропущен заблокирован: -

  1. nowait, но есть проблема с nowait. запрос записан в курсоре, когда я использовал "nowait" под курсором, запрос вернет значение NULL, и управление отключится с ошибкой, сказав - ресурс занят

  2. Я пытался с пропуском заблокирован для обновления, но если таблица содержит 5 строк и все 5 строк заблокированы, то это дает ошибку.

CURSOR cur_name_test IS SELECT def.id , def.name FROM def_map def WHERE def.id = In_id FOR UPDATE skip locked;

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Похоже, вам нужно подумать об управлении транзакциями.

Если вы выполняете работу в транзакции, то подразумевается, что эта единица работы должна быть завершена, чтобы быть действительной. Вы говорите, что некоторые операции в моей транзакции обновления не нужно завершать, чтобы транзакция была зафиксирована.

Мало того, у вас одновременно выполняются две транзакции, выполняющие операции с одним и тем же объектом. Само по себе это может быть действительным, но если это так, то вам действительно нужно вернуться к первому предложению и тщательно подумать об управлении транзакциями и процессе и посмотреть, есть ли способ, когда вторая транзакция может быть попыткой обновить только строки, которые не обновляются в первой транзакции .

0 голосов
/ 10 января 2019

Почему не использовать select только для обновления? Ниже тестируется локально в plsql разработчику.

в первом сеансе я делаю следующее

SELECT id , name
  FROM ex_employee
   FOR UPDATE;

во второй сессии я запускаю ниже, однако это зависает.

SET serveroutput ON size 2000
/
begin
declare curSOR cur_name_test IS
SELECT id , name
  FROM ex_employee
 WHERE id = 1
   FOR UPDATE ;

begin
for i in cur_name_test loop
      dbms_output.put_line('inside cursor');

end loop;

end;
end;
/
commit
/

когда я фиксирую в первом сеансе, блокировка будет снята, и второй сеанс выполнит свою работу. Я думаю, что вы хотите, бесконечное ожидание.

Однако такой механизм блокировки (пессимистическая блокировка) может привести к взаимоблокировкам, если его неправильно и тщательно не обработать (первый сеанс ожидает второй сеанс, а второй сеанс ожидает первый сеанс).

Что касается nowait, то это нормально, когда ресурс ошибок занят, потому что вы говорите, что запрос не ждет, если есть блокировка. вместо этого вы можете подождать 30, что будет ждать 30 секунд, а затем вывести ошибку, но это не то, что вы хотите (я думаю)

Что касается пропуска заблокированных, то выбор пропустит заблокированные данные, например, если у вас есть 5 строк, и одна из них заблокирована, тогда выбор не будет читать эту строку. Вот почему, когда все данные заблокированы, возникает ошибка, потому что ничего нельзя пропустить. и я думаю, это не то, что вы хотите в вашем сценарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...