Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Новый топик    Ответить
 обработка deadlock  [new]
Kru
Member

Откуда: Жуковский
Сообщений: 391
Подскажите пожалуйста можно ли в процедуре отловить и обработать ошибку deadlock.

Заранее большое спасибо
22 апр 08, 23:29    [5582468]     Ответить | Цитировать Сообщить модератору
 Re: обработка deadlock  [new]
Peter Wilson
Member

Откуда: Karaganda-> .. ->Minsk
Сообщений: 79
а на уровне базы данных разве недостаточно обработки дэдлоков???
23 апр 08, 07:13    [5582827]     Ответить | Цитировать Сообщить модератору
 Re: обработка deadlock  [new]
mustaccio
Member

Откуда: Москва -> Торонто
Сообщений: 494
Поймать-то вы его, конечно, поймаете, но обрабатывать уже будет нечего. Ловите sqlstate 40001.
23 апр 08, 07:50    [5582863]     Ответить | Цитировать Сообщить модератору
 Re: обработка deadlock  [new]
Kru
Member

Откуда: Жуковский
Сообщений: 391
Peter Wilson
а на уровне базы данных разве недостаточно обработки дэдлоков???

На уровне базы данных детектор произвольно выбирает жертву. Хотелось бы как-то в процедуре отловить что команада повисла на дедлоке и среагировать до того как об этом узнает детектор.

mustaccio
Поймать-то вы его, конечно, поймаете, но обрабатывать уже будет нечего. Ловите sqlstate 40001.


A что если поймать до того как детектор грохнет один из процессов? Может быть тогда можно что-то ещё будет сделать.

Я вот подумал, что если в процедуре установить
SET CURRENT LOCK TIMEOUT 0 и потом создать обработчик на событие недоступности ресурса с циклом в котором команада будет вызываться до тех пор пока ресурс не освободится?
Тогда может быть вообще дедлоков возникать не будет?

Что-то вроде этого:
CREATE PROCEDURE myshema.catch_deadlock()
SPECIFIC catch_deadlock
    MODIFIES SQL DATA
    NOT DETERMINISTIC
    NULL CALL
    LANGUAGE SQL
BEGIN
    DECLARE is_locked INTEGER DEFAULT 1;
    DECLARE c_is_locked CONDITION FOR SQLSTATE '57033'; 
    -- код ошибки для "Deadlock or timeout occurred without automatic rollback"

    DECLARE CONTINUE HANDLER FOR c_is_locked set is_locked = 1;

  SET CURRENT LOCK TIMEOUT 0
  /*Дока говорит что "value of 0, which means that the database manager is not to wait 
  for locks that cannot be obtained, and an error (SQLSTATE 40001 or SQLSTATE 57033) 
  will be returned"*/
  
  WHILE (is_locked = 1) DO 
  /* 
    Если есть блокировка то continue handler для condition 57033 
    установит переменную is_locked из 0 в 1 и условие для while будет Т
    так что комманда будет отправлена ещё раз.
    Если блокировки нет, то  is_locked останется 0 и произойдёт выход из цикла.
  */
    SET is_locked = 0;
    update myshema.mytable set field1 = 1 where field2 = 2;
  END WHILE;
END

Но здесь опять вопрос возникает - что будет с производительностью? Насколько больше времени уйдёт на весь этот цикл по сравнению с обычным ожиданием ресурса.

Посоветуйте пожалуйста, насколько подобный подход может быть оправдан и какая, вообще, практика считается хорошей при написании процедур заведомо обречённых на конкурренцию за ресурс.

Очень извиняюсь если коряво изложил свой вопрос.

Заранее всем большое спасибо.
23 апр 08, 22:15    [5588060]     Ответить | Цитировать Сообщить модератору
 Re: обработка deadlock  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4946
Kru
Подскажите пожалуйста можно ли в процедуре отловить и обработать ошибку deadlock.
Обработать можно, только надо иметь ввиду следующее:
Поведением менеджера при lock timeout рулить можно с помощью переменной DB2LOCK_TO_RB, т.е. либо заставить его откатывать только команду, выполнившую запрос, либо всю транзакцию (по умолчанию).
При deadlock текущая транзакция всегда откатывается.

SET LOCK TIMEOUT 0 использовать нерационально, лучше какое-нибудь допустимое небольшое значение, приемлемое для ожидания. При его истечении можно и так, как у вас, но имейте ввиду то, что я написал выше.
24 апр 08, 10:17    [5589040]     Ответить | Цитировать Сообщить модератору
 Re: обработка deadlock  [new]
Kru
Member

Откуда: Жуковский
Сообщений: 391
Mark Barinstein
Kru
Подскажите пожалуйста можно ли в процедуре отловить и обработать ошибку deadlock.
Обработать можно, только надо иметь ввиду следующее:
Поведением менеджера при lock timeout рулить можно с помощью переменной DB2LOCK_TO_RB, т.е. либо заставить его откатывать только команду, выполнившую запрос, либо всю транзакцию (по умолчанию).
При deadlock текущая транзакция всегда откатывается.

SET LOCK TIMEOUT 0 использовать нерационально, лучше какое-нибудь допустимое небольшое значение, приемлемое для ожидания. При его истечении можно и так, как у вас, но имейте ввиду то, что я написал выше.


Огромное спасибо за ответ. С DB2LOCK_TO_RB есть одно большое неудобство - её нельзя задать из процедуры. Но в моём случае, кажется будет достаточно выставить приемлемое время ожидания и потом обработать ошибку таймаута.
24 апр 08, 23:39    [5593968]     Ответить | Цитировать Сообщить модератору
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Ответить