CommitRetaining и Rollback

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Shaman
Сообщения: 4
Зарегистрирован: 09 фев 2007, 14:47

CommitRetaining и Rollback

Сообщение Shaman » 10 фев 2007, 14:25

Есть небольшая неясность (для меня) в том как поступает RollBack с изменениями закрепленными CommitRetaining.

СУБД: InterBase 7.0.1
IBX: 7.x.x (не помню)
Delphi 7

Ситуация: есть "РОБОТ", который по таймеру собирает внешние события из 2-х источников и формирует реакцию
на них (отправляет СМС и производит изменения некоторых записей в базе). Т.е. добавляет в список событий
(события однотипные - источники разные) то, что собрал. Далее - стартует транзаккию, пробегает по этому списку
в цикле вызывая хранимку, делая CommitRetaining и удаляя текущий
элемент списка. Иногда возникает ситуация, когда запись заблокирована (холостой update),
т.е. lock conflict on no wait transaction. Ситуация ловится, ошибка пишется в лог, элемент НЕ удаляется
(для повторной попытки), выполняется RollBack.
По окончании цикла - попытка Commit.

Код: Выделить всё

  
  if (not IBTransaction1.Active) then IBTransaction1.StartTransaction;
  i := 0;
  while i < LR.Count do
  try
    IBQuery1.ParamByName('XXXX').AsString := LR.Names[i];
    IBQuery1.ParamByName('XXXX').AsString := LR.ValueFromIndex[i];
    IBQuery1.ExecSQL;
    IBTransaction1.CommitRetaining;
    LR.Delete(i);
  except
    on E: Exception do
      begin
        IBTransaction2.StartTransaction;
        IBQuery2.ParamByName('XXXX').AsString := LR.Names[i];;
        IBQuery2.ParamByName('XXXX').AsString := LR.ValueFromIndex[i];
        IBQuery2.ParamByName('ERR_MSG').AsString := E.Message;
        IBQuery2.ExecSQL;
        IBTransaction2.Commit;
        Inc(i);
        IBTransaction1.RollBack;
      end;
  end;
  if (IBTransaction1.Active) then IBTransaction1.Commit;
Вопрос: что происходит с изменениями в базе, которые зафиксены CommitRetaining при RollBack,
они действительно остаются или нет?
В хелпе по IBX написано, что RollBack отменяет ВСЕ изменения в
транзакции.
В статье: http://ibase.ru/devinfo/ibtrans.htm говорится, что
CommitRetaining сохраняет изменения и продолжает работать.
Судя по записям в базе и логу СМС, Rollback все-таки сносит изменения.
Помогите разобраться, пжаллста.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 10 фев 2007, 19:08

1. для робота commitretaining не нужен, ему это только вредно. commitretaining нужен только тогда, когда некая выборка отображается пользователю, и при изменениях нужно эту же выборку не переоткрывать. Что вполне решается разнесением действий в разных транзакциях. тем более в роботе. роботу однозначно надо для чтения использовать долгую read read_committed, а для записи - короткую read_committed (или snapshot, непринципиально)

2. commitretaining это завершение транзакции с сохранением контекста - уровня изолированности. если транзакция завершалась 5 раз по commitretaining, а на 6-ой - rollback, то отменены будут разумеется только те изменения, которые были с последнего commitretaining.

Shaman
Сообщения: 4
Зарегистрирован: 09 фев 2007, 14:47

Сообщение Shaman » 10 фев 2007, 21:23

Спасибо за ответ.

По поводу п.2 ответа скажу: "Сорри. Просмотрел базу и логи истчо раз
(кстати, кто знает, как в слове из 3-х букв сделать 5 ошибок? :wink: )
- CommitRetaining + RollBack ведут себя как положено. Видимо
причина сноса была просто в том, что сносились неосуществленные
изменения (эвон как завернул :) ), т.е. произошел где-то сбой в
системе (софт, отправляющий СМС и докладающий об этом -
стороннего производителя)." :oops:

По поводу п.1. Согласен, существующее решение с использованием
CommitRetaining для робота - не есть хорошо. Но маленькое но -
софт и база достались по наследству. Надо бы всурьез перелопатить.
:shock: Не успеваю, но стараюсь. Система должна работать в режиме
24*7, постоянно приходится добавлять новые сервисы и т.д. и т.п...

Как таковая, другая реализация робота уже придумана, так что
будем побороть. :)

Да, немного для справки и некоторых шибко амбициозных новичков
(буде такие заглянут в топик. Заранее прошу прощения за тон -
ничего личного), немного о базе:

Размер базы - чуть больше Гига (пока - растет постоянно,
но я ее немного укоротил. Зы. Раза в два).
Наиболее интенсивно юзаемые таблицы имеют более
700 000,
6 000 000,
4 000 000
записей, причем 1-я и 2-я таблицы - постоянно реад, инсерт и апдейт,
3-я - инсерт.
Соответственно, бэкап/рестор - очень редко, бэкап - регулярно.
Коннектов - от 8 до 13 (круглосуточно) + 3 в удаленном офисе + роботы.
Транзакций - в среднем около 200 в минуту.
База нормально работает 2 года (тьфу-тьфу-тьфу через левое плечо),
т.е. "реального" рестора ни разу не было.
База - служба такси.
Сервак - Athlon64 3000+, 1Gb RAM, 1 SATA HDD.
Что поделать? Юзаем, что есть.
Правда шеф дал добро на приобретение "настояшего" - отказоустойчивого сервака.
И это есть гут.
Насчет всерьез перелопатить - этим и занимаюсь, деляю "пререлиз"
так сказать. Подумываю о переезде на птичку. :D

Справка дана для предъявления по месту требования. :lol:
Чтобы не кричали: "IB/FB тормозят и глюкуют".
Руки и голова должны быть на своих местах.

:wink: Где-то, толи на http://www.bash.org.ru/, толи на http://anekdot.ru/
читал речепт постановки рук на место с помощью резинки,
перекинутой через голову и привязанной к рукам.

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

Ну ладно, пора закругляться, разговорился я что-то. Видать где-то
что-то накипело.

Еще раз спасибо.

Ответить