AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 29.09.2008, 09:23   #1  
demon46 is offline
demon46
Участник
 
78 / 12 (1) ++
Регистрация: 26.06.2006
Ошибка с транзакциями!
Доброе время суток коллеги!
Свалилась на мою голову напасть не пойму почему не работает один отчет. Жалуется на непарность транзакций. Недели 3 назад все работало. Вроде ничего не менял. Нашел участок кода, который больше всего подходит к ошибке транзакций.
X++:
container run()
{
    int ret, nullret;
    ;
    this.initNeedsCalc();
    try
    {
        ttsbegin;
        [ret, nullret] = this.createNeeds();
        ttscommit;
    }
    catch (Exception::Deadlock)
    {
        retry;
    }
    catch (Exception::Error)
    {
        error(strfmt("График  %1 не обработан",
                     deliverySchedule.PurchRequestId
                    )
             );
    }
    return [ret, nullret];
}
Подскажите. Возможно если в методе createNeeds()
возникнет ошибка, то выход из исключения будет без отмены транзакции?
Эта ошибка возникает периодически, но сообщения типа "График 001 не обработан" не появляется.
Старый 29.09.2008, 09:39   #2  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Следите за appl.ttsLevel() (или в отладчике за значением tts в статусной строке).
На входе и на выходе из процедуры его вызов должен возвращать одинаковое значение. Если значение счетчика увеличивается, значит где-то во внутренних вызовах есть лишний ttsbegin.
__________________
Axapta v.3.0 sp5 kr2
Старый 29.09.2008, 09:53   #3  
demon46 is offline
demon46
Участник
 
78 / 12 (1) ++
Регистрация: 26.06.2006
AndyD
Так в отладчике редко возникает, и она не всегда возникает в рабочем режиме. Думаю может это Exception:eadlock возникает? (У нас кстати частые проблемы с блокировками в последнее время) А при возникновении исключения соответственно не выдается никакого сообщения, но при этом ошибка непарности ttsbegin ttscommit высвечивается?
Будет ли работать ttsabort по ветке условия Exception:eadlock?
Старый 29.09.2008, 12:15   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,653 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Для начала, строим тестовый Job для проверки собственных идей. У меня Ax2.5, поэтому логика может несколько отличаться в старших версиях.

X++:
static void test_TryCatchTransaction(Args _args)
{
    ;

    try
    {
        ttsbegin;
                ttsbegin;
                        throw exception::Deadlock;
                ttscommit;
        ttscommit;
    }
    catch (exception::Break)
    {
        info('exception::Break');
    }
    catch (exception::DDEerror)
    {
        info('exception::DDEerror');
    }
    catch (exception::Deadlock)
    {
        info('exception::Deadlock');
    }
    catch (exception::Error)
    {
        info('exception::Error');
    }
    catch (exception::Info)
    {
        info('exception::Info');
    }
    catch (exception::Internal)
    {
        info('exception::Internal');
    }
    catch (exception::Sequence)
    {
        info('exception::Sequence');
    }
    catch (exception::Warning)
    {
        info('exception::Warning');
    }

    info(strFmt("Количество вложенных транзакций = %1", appl.ttsLevel()));
}
Как и положено, исключение "выбрасывает" код на самый верхний уровень транзакции, автоматически откатывая все вложенные транзакции. Точнее, на обработчик Try..Catch внутри которого и расположена инициализация самого верхнего уровня транзакции. Все вложенные Try..Catch при этом игнорируются.

Однако возникают следующие вопросы:

Находятся ли команды по началу и завершению транзакции в одном методе? Внутри одного Try..Catch? По крайней мере, вызов методов по началу и завершению транзакции?

Не возникает ли ситуации, когда после выброса на верхний уровень транзакции команда по завершению транзакции оказывается вне обработчика Try..Catch?

Т.е. надо отследить вот такие программные конструкции

X++:
static void test_TryCatchTransaction(Args _args)
{
    ;

    try
    {
        ttsbegin;
                throw exception::Error;
    }
    catch (exception::Error)
    {
        info('exception::Error');
    }

    // Вот здесь возникнет ошибка
    ttscommit;

}
Старый 29.09.2008, 14:14   #5  
demon46 is offline
demon46
Участник
 
78 / 12 (1) ++
Регистрация: 26.06.2006
В методе createNeeds()
Не используются ttsbegin ttscommit. Вот блин ну где же может быть ошибка
Старый 29.09.2008, 14:29   #6  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от demon46 Посмотреть сообщение
В методе createNeeds()
Не используются ttsbegin ttscommit. Вот блин ну где же может быть ошибка
А до вызова метода run() нигде транзакция не открывается?
с этими непарными транзакциями вечно морока, пока найдешь откуда ползет поседеешь
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 29.09.2008, 14:57   #7  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Можно попробовать отловить ошибку, используя методы Application.ttsNotifyBegin() и Application.ttsNotifyCommit(). К примеру, можно дописать в них код, который, если текущий пользователь такой-то (чтоб срабатывало не у всех), записывал в какой-нить лог информацию о том, откуда вызван метод (см. Global::callStack2Infolog()) и какой текущий уровень транзакций на момент вызова метода, а в ttsNotifyCommit() сделать дополнительную проверку на то, что до вызова этого метода appl.ttsLevel() уже равен нулю, и поставить точку останова на этой ветке кода, чтобы отловить ее в отладчике. Тогда можно будет, по крайней мере, до вылета ошибки посмотреть, где именно она возникает, а по созданному логу отследить момент, когда ttsbegin/ttscommit разбалансируются (ведь предположительно они должны вызываться в рамках одного метода). Ну и погонять ваш отчет под "нужным" пользователем до момента возникновения ошибки.
За это сообщение автора поблагодарили: lev (1), demon46 (1).
Старый 29.09.2008, 15:06   #8  
demon46 is offline
demon46
Участник
 
78 / 12 (1) ++
Регистрация: 26.06.2006
gl00mie Благодарю. Дельный совет!
Старый 29.09.2008, 16:11   #9  
demon46 is offline
demon46
Участник
 
78 / 12 (1) ++
Регистрация: 26.06.2006
gl00mie
Какая-то фигня отображается.
Вот что я дописал.
X++:
void ttsNotifyCommit()
{
    str User;
    ;
    User = CurUserid();
    if (User == 'dgol' || User == 'ipas' || User == 'robo')
    {
        info("LEVEL "+Num2Str(appl.ttsLevel(),1,0,1,0));
        Global::callStack2infolog();
    }
    if (appl.ttsLevel()==0)
        info("Error");
    this.inventUpdateTTSControl().ttsNotifyCommit();
    this.numberSeqGlobal().ttsNotifyCommit();
}
А при вызове ttscommit всегда уровень транзакции равен 0 и отображается в инфологе "Еrror"
а стек вызова всегда "\Classes\Application\ttsNotifyBegin 9"
Старый 29.09.2008, 16:56   #10  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Мда, все оказалось не так просто... По ходу ttsNotifyBegin()/ttsNotifyCommit() вызываются только после соотв. начала/завершения транзакции и лишь тогда, когда ttslevel < 1, т.е. для вложенных ttsbegin/ttscommit этим методы уже не вызываются А что касается стека вызовов, то у меня, к примеру, получается вот что:

здесь в методе SysSetupFormRun.task() в указанной 49-й строке вызывается super()
Старый 29.09.2008, 17:08   #11  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Коллега высказал мнение, что ошибка с не балансирующими транзакциями может еще возникать, если внутри транзакции открывается какая-то форма. Это можно проверить, поставив заглушку в \Classes\SysSetupFormRun\init, проверять там текущий appl.ttsLevel() и, если он ненулевой, писать тот же стэк вызовов куда-нибудь...
За это сообщение автора поблагодарили: evv (1).
Старый 29.09.2008, 18:43   #12  
Hyper is offline
Hyper
Участник
Соотечественники
 
163 / 29 (1) +++
Регистрация: 09.10.2003
Цитата:
Сообщение от gl00mie Посмотреть сообщение
если внутри транзакции открывается какая-то форма.
Чего всеми силами надо избегать.
Старый 06.10.2008, 09:15   #13  
demon46 is offline
demon46
Участник
 
78 / 12 (1) ++
Регистрация: 26.06.2006
А текущий уровень транзакций TTS - 1. (в диалоге, когда возникает ошибка транзакций) Это до выполнения операции с транзакциями или уже после появления ошибки?
И вобще отчет разделен на 2 части. В одной формируются журналы, а во второй происходит рассылка почтовых сообщений информирующих о создании журналов. Так вот сегодня у меня ошибка вывалилась во второй части, где нет никаких транзакционных скобок. Там просто выбираются номера журналов из таблицы, и с помощью EXCEL формируются вложенные файлы, а затем при помощи Postie отправляются письма. Может быть это связано с совместным доступом к журналу?
Старый 06.10.2008, 13:19   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от demon46 Посмотреть сообщение
А текущий уровень транзакций TTS - 1. (в диалоге, когда возникает ошибка транзакций)
Значит баг уже случился.

По идее вариант gl00mie помогает поймать баг в момент возникновения. А когда вылезла форма о том, что тарнзакции не балансируют - то как говорится уже "поздняк метаться".
Теги
транзакции

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Ошибка (?) при печати приходного ордера в DAX 4.0 SP2 Ivanhoe DAX: Программирование 7 19.01.2021 14:13
Не запускается Axapta. Общая ошибка сети. Lucky13 DAX: Администрирование 3 25.09.2007 13:02
Ошибка в формате числа. 36AC DAX: Программирование 7 19.10.2006 10:04
Ошибка при обработке С-Ф Sergo DAX: Программирование 7 20.01.2006 11:56
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:10.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.