Дедлок и как с ним бороться

dmidek
Дата: 11.08.2005 16:35:33
Уважаемые господа!
У меня случился дедлок TX .
Сценарий вот какой:
Сессия 1 :
select akt_stand_nr from tbl_SID where sid= 4055000000021
for update wait 3
-- 1 row selected

Сессия 2 :
select akt_stand_nr from tbl_sid where sid = 4055000000022
for update wait 3
-- 1 Row selected

Сессия 1 :
select akt_stand_nr from tbl_sid where sid = 4055000000022
for update wait 3
-- Сессия ждет три секунды окончания транзакции в сессии 2.

-- В течение этих 3 секунд.
Сессия 2 :
select akt_stand_nr from tbl_SID where sid = 4055000000021
for update wait 3
-- Дедлок (по русски как-то жутковато выглядит )

Мы заметили, что виноват всегда один и тот же "SELECT FOR UPDATE wait 3
В обоих сессиях. К сожалению мы не можем без него обойтись, очень много сессий бежит параллельно и обновляет искомое значение akt_stand_nr.
Как рабочий вариант был предложен метод «Моряк не спорит с рифами, он их обходит“

DECLARE
EXC_DEADLOCK EXCEPTION;
PRAGMA EXCEPTION_INIT (EXC_DEADLOCK, -00060);
...
BEGIN
BEGIN
select akt_stand_nr into v_dummy from TBL_SID where sid = v_sid
for update wait 3;
EXCEPTION
WHEN EXC_DEADLOCK
THEN
dbms_output.put_line('Deadlock! ');
SELECT akt_stand_nr into v_dummy from tbl_sid where sid = v_sid;
END;
................
END;

И вот тут меня охватили сомнения. Я замечаю, что дедлок постоянно выпадает в сессии 1 , а не в сессии 2. Это закономерность ? Если да , то плохо ли это в нашей ситуации ?
И вообще , обход дедлока – это приемлемо или так себе. (Заметьте, что в exception я делаю тот же SELECT только без WAITa , a la «OK, дай хоть какое- нибудь значение»)
Спасибо
Александр Соколов
Дата: 11.08.2005 16:59:22
dmidek
Я замечаю, что дедлок постоянно выпадает в сессии 1 , а не в сессии 2. Это закономерность ? Если да , то плохо ли это в нашей ситуации ?
И вообще , обход дедлока – это приемлемо или так себе.


Oracle
Oracle автоматически распознает возникновение взаимоблокировок и разрешает их путем отката одной из операций, вовлеченной во взаимоблокировку и тем самым снимает один набор конфликтующих блокировок строк. Транзакции, в которой производится откат на уровне операции, возвращается соответствующее сообщение. Операция, подвергнутая откату, принадлежит транзакции, которая обнаружила взаимоблокировку. Обычно транзакция, подавшая сигнал о взаимоблокировке, должна откатываться явно, но через некоторое время она может повторить неудачно завершившуюся операцию.
Dimension 5
Дата: 11.08.2005 17:08:10
Deadlock в Оракле - позор для программера...

Сессия которая на свою беду обнаружит deadlock:
1. Откатывает последий statement с ORA - xxxx (deadlock detected)
2. Если не установлен обработчик на ORA - xxxx (deadlock detected) - откатывает транзакцию + трейс в udump
softy
Дата: 11.08.2005 17:15:30
Не нужно бороться с дедлоками - с ним бореться сам Oracle.
Vadim_Maximov
Дата: 11.08.2005 17:17:26
softbuilder@inbox.ru
Не нужно бороться с дедлоками - с ним бореться сам Oracle.
Подписался. Бороться нужно с причинами, а не со следствием.
dmidek
Дата: 11.08.2005 17:19:14
IMHO не очень хорошо он с ними борется. Почему он вообще создает дедлок, если стоит WAIT 3 ? Он не понимает, что через 3 секунды я сам уйду ?
hell
Дата: 11.08.2005 17:39:23
dmidek
IMHO не очень хорошо он с ними борется. Почему он вообще создает дедлок, если стоит WAIT 3 ? Он не понимает, что через 3 секунды я сам уйду ?


Вопрос, зачем вы вообще блокируете запись? Из предложенного вами решения следует, что в случае дедлока вы просто выбираете значение и продолжаете работать, а что делаете если блокировка не удалась в течении 3 секунд? Если тоже самое - зачем вам вообще эти блокировки?


Короче, расскажите больше про задачу :-)
Stax.
Дата: 11.08.2005 17:54:01
Dimension 5

...
2. Если не установлен обработчик на ORA - xxxx (deadlock detected) - откатывает транзакцию + трейс в udump
...

Вы уверены что откатит транзакцию?
ps
имхо не откатит
softy
Дата: 11.08.2005 17:59:59
Для кого был дедлок - для того откатит.
--
Дата: 11.08.2005 18:04:31
как вариант for update nowait и обработка 54 исключения (если подходит по условиям задачи)