Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
Здравствуйте коллеги! Некогда писался наскоро код для полевых условий (однопоточное приложение - один клиент), сейчас нагрузка возросла (много клиентов) и начали появляться deadlock'и.
Суть: есть хранимая, которая обновляет некоторое количество строк в таблице, изменяя значение одного поля. Раньше, хранимую дёргало одно приложение в одном потоке, сейчас много во многих.
По трейсам вижу, что блокируют друг друга 2 сессии, каждая из которых, выполняя update, запрашивает ексклюзивную блокировку (waits - X) строчки, которая уже занята другой сессией.

Поможет ли в этом случае упорядоченный UPDATE? То есть такой, который бы всегда блокировал строчки в строго определённом порядке (например по значению числового PK). Мне представляется что-то вроде этого:

FOR recRow in (SELECT col1 FROM my_table ORDER by col_PK) 
LOOP
  UPDATE my_table SET col1 = :newValue
  WHERE CURRENT OF recRow;
END LOOP;

Спасибо за ваши советы!
6 апр 09, 18:40    [7028784]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
Исправляюсь...

FOR recRow in (SELECT col1 FROM my_table ORDER by col_PK) 
LOOP
  UPDATE my_table SET col1 = :newValue
  WHERE col_PK = recRow.col_PK;
END LOOP;
6 апр 09, 19:00    [7028867]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
miksoft
Member

Откуда:
Сообщений: 38540
тогда уж
(SELECT col_PK FROM my_table ORDER by col_PK)
6 апр 09, 19:02    [7028876]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
miksoft ваша правда, поспешишь - ...

ну собственно от проблемы меня этот способ не избавил - блокировки всё равно остались
6 апр 09, 19:04    [7028882]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Timm
Member

Откуда: Moscow, Ё-burg
Сообщений: 3696
Поможет. Лучше сделать вообще без цикла:
update (select * from t order by <>) set ...
6 апр 09, 19:04    [7028883]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
Не помогло...
Похоже я упустил из виду факт того, что сама таблица пополняется из разных сессий, следовательно PK (числовой, выдаваемый из sequence) тут не ориентир (ввиду особенностей работы сиквенсов).
Попробую ориентироваться на дату поступления записи в таблицу и сортировать по этому полю
6 апр 09, 19:34    [7028980]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
arttry
Member

Откуда:
Сообщений: 42
курсор "select for update" не спасет?
они блокируют строки и не дают другому выбирать на апдейт те же строки
7 апр 09, 14:39    [7033140]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
wildwind
Member

Откуда: Москва
Сообщений: 1296
Gu-est,

Вы бы показали как сейчас.
7 апр 09, 15:49    [7033911]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
Попытался сделать так:

UPDATE (SELECT * FROM my_table ORDER BY mytbl_insert_date) 
    SET mytbl_somecolumn =nValue;

Где mytbl_insert_date DEFAULT SYSDATE - дата регистрации (появления) записи. Тоже не помогло. Думаю поднять уровень изолированности этой транзакции до SERIALIZABLE и обрабатывать неудачные попытки закоммититься
7 апр 09, 16:03    [7034043]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
bigsov
Member

Откуда:
Сообщений: 282
присоединяюсь к arttry и предлагаю реализовать механизм пессимистичной блокировки, например так:
SELECT FOR UPDATE ... NOWAIT
7 апр 09, 16:07    [7034089]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
deadlock - это же не просто блокировка, это блокировки в противоположных порядках. ИМХО Вам надо смотреть именно в эту сторону. То бишь, если у Вас один тех. процесс делает:
- блокировка А
- блокировка Б
А второй - в начале Б, потом А. То подумать, чтобы в одном из них заблокировать одинаковый же ресурс(имеется ввиду, конечно, не update поднять выше, а просто for update Б сделать, например, перед блокировкой А).
Это, конечно, слишком примитивная схема, но это то, с чего следует начать. При ветвистых, друг из друга вызываемых процессах - нетривиальная задача.
7 апр 09, 16:14    [7034183]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
wildwind
Member

Откуда: Москва
Сообщений: 1296
Gu-est,

Я имел в виду чтобы вы показали как выглядела ХП до ваших попыток, когда "хранимую дёргало одно приложение в одном потоке". И фрагмент трейса заодно.
7 апр 09, 16:25    [7034291]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Timm
Member

Откуда: Moscow, Ё-burg
Сообщений: 3696
Gu-est
Не помогло...

См. пост Jannny выше.
7 апр 09, 16:26    [7034301]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
2Jannny
Суть ведь в одном и том же - что сначала явно блокировать записи в определённом порядке (всегда в одном и том же), а потом изменять их в произвольном, либо сразу их изменять в "правильном" порядке?
7 апр 09, 17:06    [7034698]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
Вынес этот пересчёт в отдельную транзакцию (вообще в джоб) с уровнем изоляции - SERIALIZABLE. Обрабатываю исключение "ORA-08177: can't serialize access for this transaction" и плюю в потолок, потому что как минимум одна из двух конкурирующих транзакций отработала, а мне большего и не надо :)

Надо будет подумать в сторону SELECT FOR UPDATE, но есть подозрение что при блокировании записей будет тот же DEADLOCK, что я ловил при упорядоченном UPDATE.
7 апр 09, 19:27    [7035626]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Gu-est
2Jannny
Суть ведь в одном и том же - что сначала явно блокировать записи в определённом порядке (всегда в одном и том же), а потом изменять их в произвольном, либо сразу их изменять в "правильном" порядке?
Вопрос в том, что изменение порядка записей на одинаковый Вам не помогло, следовательно, Ваше предположение, что именно это было причиной deadlock - скорее всего неверно. Вам alert.log точно именно на это указал?

Gu-est
Вынес этот пересчёт в отдельную транзакцию (вообще в джоб) с уровнем изоляции - SERIALIZABLE. Обрабатываю исключение "ORA-08177: can't serialize access for this transaction" и плюю в потолок, потому что как минимум одна из двух конкурирующих транзакций отработала, а мне большего и не надо :)
Надеюсь, Вы понимаете, что делаете :)
8 апр 09, 10:41    [7037168]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
Gu-est
Guest
автор
Вам alert.log точно именно на это указал?


Да, трейс файл, на который ссылается alert.log, указывает на взаимную блокировку именно этих двух UPDATE'ов.

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


Да, похоже я также промахнулся с причиной. А причина в том, что во время выполнения UPDATE'ов из разных сессий, в таблице могут появится новые записи, которые блокируются одной сессией первыми, а другой - последними. Где-то читал про перезапуск UPDATE'ов, если под предикат-условие в процессе выполнения попадают новые записи - похоже мой случай.

автор
Надеюсь, Вы понимаете, что делаете :)

Для меня (для бизнес-логики конечно же) важно чтобы выполнился хотя бы один апдейт - эдакое допущение. Поэтому отдельная транзакция/сессия из джоба с уровнем изолированности ISOLATED меня тут спасла.

Но про блокировки чую надо перечитать концептс, память заржавела
8 апр 09, 12:46    [7038209]     Ответить | Цитировать Сообщить модератору
 Re: ORA-00060 DEADLOCK DETECTED. Нужен совет по редизайну  [new]
August
Member

Откуда:
Сообщений: 62
уже говорилось
select for update
8 апр 09, 13:17    [7038416]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить