Предыстория. Есть машинка с 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.