Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
Здравствуйте.

Есть два сеанса, каждый из которых может попытаться выполнить апдейт одной и той же строки на длительное время (так нужно по бизнес-логике).
Вопросы.
1) Как правильно сделать так, чтобы при попытке апдейта занятой строки сеанс немедленно получал сообщение о неудаче этого действия ? Если пытаться через
select id into v_id from tmp where object_id=a_required_obj for update nowait
- то при неуспехе в переменной v_id не будет записан соотв-щий id - а нам нужно, чтобы он оказался в этой v_id независимо от того, удалось ли заблокировать строку или нет.
2) Можно ли внутри пакетной ХП, где это всё выполняется, менять (временно) уровень изолированности трн или это "не комильфо" ?
3) Может ли ХП узнать, в каком уровне изолированности трн она выполняется ?
22 фев 11, 12:00    [10272584]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
AmKad
Member

Откуда:
Сообщений: 5222
Штопор,

Сначала читай, потом блокируй.
22 фев 11, 12:07    [10272677]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2170
Штопор
3) Может ли ХП узнать, в каком уровне изолированности трн она выполняется ?
Usage NotesThe SET TRANSACTION statement must be the first SQL statement in the transaction and can appear only once in the transaction.
22 фев 11, 12:16    [10272756]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2170
--Eugene--,

ой, не тот вопрос написал :)
22 фев 11, 12:17    [10272763]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
--Eugene--,

да, по поводу set tran я уже прочитал, спасибо.
Что получается, для попытки апдейта занятой строки с немедленным отлупом при неудаче, но необходимостью получить-таки тот id, который оказался недоступным, надо городить вот это:
begin
  ...
  select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id;
  select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id for update no wait;
  update cfgblocking
    set user_id = a_user_id,  cfg_object_id = a_cfg_object_id, date_blocking = sysdate
    where id = v_id;
exception 
    when resource_busy then
        ...
- правильно я понял ?
22 фев 11, 12:28    [10272854]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2855
Штопор,

Если id не меняется в процедуре, то что огород городить?
Если меняется, то может подойдет
select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id;
select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id and id = v_id for update no wait;
22 фев 11, 12:32    [10272883]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2170
Штопор,

лучше не ID, а ROWID.
22 фев 11, 12:32    [10272884]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
так будет лучше
Guest
Штопор
--Eugene--,

да, по поводу set tran я уже прочитал, спасибо.
Что получается, для попытки апдейта занятой строки с немедленным отлупом при неудаче, но необходимостью получить-таки тот id, который оказался недоступным, надо городить вот это:
begin
  ...
  select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id;
  select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id for update no wait;
  update cfgblocking
    set user_id = a_user_id,  cfg_object_id = a_cfg_object_id, date_blocking = sysdate
    where id = v_id;
exception 
    when resource_busy then
        ...
- правильно я понял ?

  select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id for update nowait;
  update cfgblocking
    set user_id = a_user_id,  cfg_object_id = a_cfg_object_id, date_blocking = sysdate
    where id = v_id;
exception 
    when resource_busy then
    select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id;
22 фев 11, 12:33    [10272889]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
--Eugene--
Штопор,

лучше не ID, а ROWID.

А между тем, параллельно - delete/insert с тем же ROWID, но другим ID.
22 фев 11, 12:36    [10272911]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2170
declare
	-- ORA-00054: resource busy and acquire with NOWAIT specified
	resource_busy exception;
	resource_busy# constant pls_integer := -00054;
	pragma exception_init(resource_busy, -00054);
	r rowid;
begin
	select [b]rowid[/b], ...
		into r, ...
		from t
		where ...
		for update nowait;
	update t
		...
		where [b]rowid[/b] = r;
exception
	when resource_busy then
		...
end;
22 фев 11, 12:36    [10272913]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
AlexFF__|,

Id конечно же НЕ меняется :-) Он нужен только для того, чтобы сформировать на его основе сообщение юзеру, типа такого: "объект с ид=654789 (<имя_объекта_пользовательское>) сейчас ЗАНЯТ пользователем <имя_занявшего>".
22 фев 11, 12:37    [10272921]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
_Nikotin
--Eugene--
Штопор,

лучше не ID, а ROWID.

А между тем, параллельно - delete/insert с тем же ROWID, но другим ID.
Увы, ID мы менять не можем. На них очень много чего завязано.
22 фев 11, 12:38    [10272927]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2170
_Nikotin
А между тем, параллельно - delete/insert с тем же ROWID, но другим ID.

но ведь в начале ты блокируешь запись с этим ID
22 фев 11, 12:39    [10272936]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
--Eugene--
declare
	-- ORA-00054: resource busy and acquire with NOWAIT specified
	resource_busy exception;
...
- спасибо, так и сделаем.
22 фев 11, 12:40    [10272944]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
--Eugene--
_Nikotin
А между тем, параллельно - delete/insert с тем же ROWID, но другим ID.

но ведь в начале ты блокируешь запись с этим ID

Я думал ты и тут хотел использовать ROWID:
select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id;
select id  into v_id from cfgblocking where cfg_object_id = a_cfg_object_id for update no wait;


Штопор
_Nikotin
А между тем, параллельно - delete/insert с тем же ROWID, но другим ID.
Увы, ID мы менять не можем. На них очень много чего завязано.

Никто и не меняет, просто удаляется старая/вставляется новая строка на то же место.
22 фев 11, 12:43    [10272967]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
_Nikotin
Никто и не меняет, просто удаляется старая/вставляется новая строка на то же место.
Нельзя ли поподробнее объяснить ?
Вот есть сеанс "А", ему нужна строка с ИД=654789. Допустим, он её успешно заблокировал, выполнил в ней апдейт и далее "сидит" в этой строке (держит её).
Дальше сеансу "Б" понадобилась строка с этим же ИД.
Он её пытается заблокировать - фиг.
Что дальше будет происходить ? кто-чего удалит и добавит ?
22 фев 11, 12:49    [10273028]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Штопор
_Nikotin
Никто и не меняет, просто удаляется старая/вставляется новая строка на то же место.
Нельзя ли поподробнее объяснить ?
Вот есть сеанс "А", ему нужна строка с ИД=654789. Допустим, он её успешно заблокировал, выполнил в ней апдейт и далее "сидит" в этой строке (держит её).
Дальше сеансу "Б" понадобилась строка с этим же ИД.
Он её пытается заблокировать - фиг.
Что дальше будет происходить ? кто-чего удалит и добавит ?

дальше - приложение должно обработать эту ситуации, в соответствие с её (ситуации) бизнес-логикой
22 фев 11, 13:03    [10273126]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2170
orawish
дальше - приложение должно обработать эту ситуации, в соответствие с её (ситуации) бизнес-логикой

да он не о том спрашивает.
его заинтересовала фраза
_Nikotin
Никто и не меняет, просто удаляется старая/вставляется новая строка на то же место.
22 фев 11, 13:07    [10273161]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
Штопор
Guest
orawish
дальше - приложение должно обработать эту ситуации, в соответствие с её (ситуации) бизнес-логикой
Это понятно. Мне не ясно то, про что сказал _Nikotin: удаление и инсерт ДРУГОЙ записи с ТЕМ ЖЕ САМЫМ Id. Кто будет делать это ? сеанс "Б" не сможет, т.к. ИД = первичный ключ, а такой же ИД уже задействован в записи, которую держит сеанс "А".
След-но, удалять и добавлять должен сеанс "А".
Что это даст, если вслед за этим сеанс "Б" опять попытается заблокировать строку с этим же ИД ?
Короче, я не понял эту идею с "параллельными удалениями и инсертами".
22 фев 11, 13:07    [10273168]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать update tmp where id = v_id с немедленным отвалом при невозможности этого ?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Штопор,

Если заблокировал то такого не произойдёт, проблема могла бы быть если
-- В параллельной сессии кто-то удаляет строку с cfg_object_id = a_cfg_object_id 
-- и вставляет новую с другим cfg_object_id, но так что ROWID оказывается тот же
select rowid into rid from cfgblocking where cfg_object_id = a_cfg_object_id;
-- В параллельной сессии делается commit;
select id into v_id from cfgblocking where rowid = rid for update no wait;
22 фев 11, 13:10    [10273193]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить