Предыстория. Есть машинка с NT4 на которой много лет крутятся application-сервера. В том числе складской. Безо всяких нареканий. Есть на нём одна процедурка-метод, завершение складской операции отгрузки, выглядящая примерно так:

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

Все обращения к FB идут вот в таких траях:
   Try Exec...
     Except On E:Exception Do
      if Pos('deadlock',E.Message)>0 then
       begin IBTrExec.RollBack;
        OnceMore:=True; Inc(TryCount);
       end
      else
       begin IBTrExec.RollBack;
         Answer:='E~O@';
         frIBSklFace.LogFile(MyConnection,'OtgrSave идентификатор шага'+
                           IntToStr(MainOper), E);
         Result:=Answer; Exit;
       end;
    end;
    if OnceMore then GoTo L1;
(L1 - самое начало, старт транзакции, там счётчик на 6 повторов и уж только тогда доклад клиенту)

IBX патченый, в смысле экзерсисы со скрытым повтором вызовов IBStoredProc в той же транзакции снесены под корень. Транзакция снапшот, Default action - rollback. Фокусы Джеффа с default action тоже приведены в чуйство. Работало всё без нареканий лет 8 точно, при всяких разных завалах, ручных аварийных абортированиях аппсерверов, обрывах связи со складом и ошибках персонала данные не страдали.

История. 2-го числа что-то поплохело машинке. Хрен его знает какой там был аптайм у NT4, с полгода наверное, админ люлей получил. Но не в этом ссуть. Короче, ушла она в себя совсем и на внешние раздражители не реагировала. Пришлось повер нажимать. Загрузилась, всё путём, работаем дальше. Однако, на днях некоторые товары на складе пошли в минус. Расследование показало, что сохранение отгрузки, завершавшейся в момент, когда машинка издохла, выполнилось 2 раза. То есть, либо не прошёл rollback в одном из траев и цикл повторных попыток повторился, либо не сохранился штамп завершено и сохранились остальные изменения и оператор после перезагрузки клиента увидел её как незавершённую (утерянное DCOM-соединение по-хитрому мы не восстанавливаем, валим клиента с грохотом). Оператор не помнит, повторял он завершение или нет. В логе аппсервера никаких необычных записей нет, только начала-концы сеансов работы. Не хочется думать о том, что какими-то нечистыми силами возможно добиться неполного отката транзакции по явному rollback или аварийному отпаду клиента. Тем более, что этого не наблюдалось много лет. Хочется верить, что НТюк в агонии умудрился попереставлять битики и трансформировать rollback в коммит, или попутал True и False в OnceMore, выполнил цикл-повтор по конфликту, которого не было и соответсвенно не было роллбака, и закоммитил двойной результат, после чего издох окончательно. Но осадок остался.

--
Regards. Ded.

Ответить