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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.10.2021, 15:31   #1  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Как найти вызов ttsBegin
Пользователь работает и где-то код криво отрабатывает и возникает незакрытая транзакция. У пользователя разнесся журнал ГК. Потом он видит что все глючит, кнопки не работают. Перезаходит - журнала нет.

Работает с журналом ГК, сопоставления ручные, отчеты попутно смотрит. Возникает 1-2 раза в день и не каждый день. От нее добиться последовательность глюка не могу. Сидеть с ней тоже. Вижу уже итог.
Хотел настроить логирование для нее, чтобы поймать момент ttabegin, ttscommit.
Добавил код в Apllication \ ttsNotifyAbort, ttsNotifyCommit,ttsNotifyPostBegin. И с помощью xSession::xppCallStack() хочу стэк вызовов последнего не закрытого ttsBegin найти. Но там только:
X++:
(S)\Classes\Test\logAdd 18
(S)\Classes\Application\ttsNotifyPostBegin 6
Т.е. откуда это пришло вообще не понять..
Просто смотреть код вокруг объектов которые пользователь якобы использовал в последние минуты - на вскидку не помогло..

Есть у кого-то опыт поиска источника подобных проблем?

Дакс4.
Старый 07.10.2021, 15:46   #2  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Perc Посмотреть сообщение
Но там только:
X++:
(S)\Classes\Test\logAdd 18
(S)\Classes\Application\ttsNotifyPostBegin 6
Т.е. откуда это пришло вообще не понять.
Поймать стек вызова у долгой транзакции.
Попробуйте в параметрах AOS включить точки останова на уровне сервера
Старый 11.10.2021, 05:08   #4  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Поймать стек вызова у долгой транзакции.
Попробуйте в параметрах AOS включить точки останова на уровне сервера
Да, посмотрел тему. У людей такая же проблема со стеком вызовов. При вызове tts с клиента - источник не отслеживается..
Кстати заметил разницу при вызове xSession::xppCallStack() на клиенте и на сервере. При вызове с клиента иногда более информативно получается, но в моей проблеме не помогло.

Точки останова само собой включены.

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

А нет, так подумываю уже о временной возможности тотальной замены всех ttsbegin на вызов ttsbegin с серверной процедуры)
Старый 11.10.2021, 05:18   #5  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
От отсутствия вариантов попробовал и представленный анализатор. Предупреждений он навалил достаточно конечно. Но там все не существенно.

Ошибок - 95% не справился с методами в которых есть синтаксис clr.(обработка под 3-ку делалась) А остальные десяток мест из кого-то заброшенного функционала который уже нигде и никем у нас не используется. Выявился один рабочий отчет с return между tts. Но по факту оказалось, что тоже не рабочее место..
Старый 11.10.2021, 07:03   #6  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
В аксапте была табличка лога sysutilelementslog или как то так.
Там логировалис используемые юзером формы и очеты.
Несложной доработкой можно обобщить до классов.
Тем самым еще сузить область поисков.
Старый 11.10.2021, 08:21   #7  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от Logger Посмотреть сообщение
В аксапте была табличка лога sysutilelementslog или как то так.
Там логировалис используемые юзером формы и очеты.
Несложной доработкой можно обобщить до классов.
Тем самым еще сузить область поисков.
В четверке нет такого логирования. Ну да ладно.. посмотрим в версии выше..

Несложной это какой? за созданием форм слежение из \xClassFactory\formRunClass сделано. Как бэ системой поддерживается..
А класс на что зацепится?
Старый 11.10.2021, 09:46   #8  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Perc Посмотреть сообщение
А класс на что зацепится?
Я в 4-ку перетаскивал из 2009-й
Еще добавил тут
\Classes\RunBase\new
\Classes\ClassFactory\createClass

помогает для Runbase а также для всего что по менюитем запускается. Конечно это не все классы охватывает но очень многое.
Также можно вот это применить
это одна из идей, которую я хочу пропихнуть в АХ 2012.

Ошибка с транзакциями!
Старый 01.11.2021, 12:25   #9  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
В итоге xSession::xppCallStack() оказался совершенно бесполезным в поиске проблемы.
Самым простым и действенным получилось в onEventGoingIdle показать модальное окно после проверки ttsLevel. С третьей попытки пользователь таки прочитал сообщение и позвонил)

Проблема была на форме LedgerJournalTable. Ктото у нас на modified одного из полей сделал LedgerJournalTable_ds.write(). А во write на форме:
X++:
    ttsbegin;
    super();
    journalFormTable.datasourceWritePost();
    ttscommit;
Одно из обязательных полей таблицы было не заполнено. Поэтому в validateWrite() в super() аксапта поднимает какое то странное исключение с типом Warning. При этом код в validateWrite() доделывается, а все что было выше по стэку бросается, и транзакция еще не откатывается. В итоге имеем ttslevel=1. Далее пользователь умудряется все корректно заполнить, создать строки и разнести журнал. Потом аскапта совсем уж начинает сопротивляться, пользователь перезапускается - но журнала который он видел разнесенным, уже нет)
По мне write() в коде не выглядит каким то уж криминалом. А вот реакция системы с бросанием кода, но без отката транзакции - непонятно.. Предполагается что? Написать еще дополнительно проверку validateWite перед wite?
За это сообщение автора поблагодарили: S.Kuskov (5).
Старый 01.11.2021, 13:32   #10  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Perc Посмотреть сообщение
Написать еще дополнительно проверку validateWite перед wite?
Почему нет. Неплохой вариант. Ну еще try catch добавить.
Старый 01.11.2021, 14:25   #11  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от Logger Посмотреть сообщение
Почему нет. Неплохой вариант. Ну еще try catch добавить.
Да все это выглядит как ересь. Затыкание багов(фитчей) ядра. По мне LedgerJournalTable_ds.write() уже должно включать весь сервис. Оно и включает, но как-то "не так". Или должна быть функция у DS которая аналог Ctrl+S.

Кстати вместо LedgerJournalTable_ds.write() я написал element.task(#taskSave) и все заработало аналогично Ctrl+S. Тогда сначала formRun запускает validateWrite, а потом только write. И тогда все срабатывает более менее адекватно.

Но по итого приходится разобраться зачем все это писали, и видимо вынесу ваще все что хотели сделать на update таблицы. И дело с концом..

Но в любом случае, работа исключений в validateWrite на форме - подкинула нежданчик..

Последний раз редактировалось Perc; 01.11.2021 в 14:32.
За это сообщение автора поблагодарили: Logger (3).
Старый 01.11.2021, 14:49   #12  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Не понятно, где тут баг ядра, если источник проблемы в том что-то у вас в modified написал .write() - что делать, в целом, не стоит никогда.
Старый 01.11.2021, 15:11   #13  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от Pandasama Посмотреть сообщение
у вас в modified написал .write() - что делать, в целом, не стоит никогда.
А это откуда такой смелый вывод?
Принципиальной разницы нет - modified, clicked...
Почему DS.executeQuery() можно написать, а DS.write() нельзя?
DS.write() незримо написан на любой кнопке со свойством SaveRecord=Yes

Какие нерушимые принципы нарушены таким вызовом? Надо пояснять.. а так это блабла.. извините)
Старый 01.11.2021, 15:30   #14  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Это, конечно, оффтоп, но на мой взгляд вешать логику сохранения ЛЮБОЙ (не обязательно текущей) записи в событие modified поля - это отвратительный дизайн.
Хуже только вешать в событии validateField.
Старый 01.11.2021, 16:11   #15  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от Pandasama Посмотреть сообщение
Это, конечно, оффтоп, но на мой взгляд вешать логику сохранения ЛЮБОЙ (не обязательно текущей) записи в событие modified поля - это отвратительный дизайн.
Хуже только вешать в событии validateField.
У меня нет претензий к тому чтобы считать, что это плохой дизайн. У меня претензия к тому что вы очень быстро связали мою изначальную ошибку незакрытого ttsBegin с якобы плохим дизайном. И прикопались к modified.. такая проблема выскочит при программном вызове DS.write() из любого места.
Старый 01.11.2021, 23:15   #16  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Perc Посмотреть сообщение
Одно из обязательных полей таблицы было не заполнено. Поэтому в validateWrite() в super() аксапта поднимает какое то странное исключение с типом Warning.
Зачем вообще validateWrite бросает исключение? Разве он не должен просто вернуть false
Старый 02.11.2021, 07:25   #17  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Зачем вообще validateWrite бросает исключение? Разве он не должен просто вернуть false
ну так а что системе еще делать? validateWrite система сама вызвала в супере write. validateWrite вернул false - поле обязательное не заполнено. Проверял - поднимается
исключение типа info, выполнение обрывается, транзакция не откатывается системой. Но при этом если запихать вызов ds.write в try catch - то в catch ловится ttslevel уже ноль. Т.е. чтобы система сама откатила транзакцию достаточно поместить вызов в try. Это в 4-ке.
В 12-ке проверил - такой проблемы нет. Точно в таком же случае - транзакция абортируется в любом варианте.

Посмотрел стандартный sys-код в 4ке в этой же форме. MS проблему учитывали и писали с validateWrite:
X++:
void fieldModifiedBlockUserGroupId()
{
    if (! journalTable_ds.validateWrite())
        return;

    journalTable_ds.write();
    journalTable_ds.refresh();
}
этот метод они вызывают в modified поля формы.
За это сообщение автора поблагодарили: sukhanchik (2).
Старый 02.11.2021, 08:12   #18  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Цитата:
поднимается исключение типа info
где поднимается? в super() validateWrite ? или явно throw info в validateWrite, которое не прерывает транзакцию?
Старый 02.11.2021, 09:37   #19  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от Pandasama Посмотреть сообщение
где поднимается? в super() validateWrite ? или явно throw info в validateWrite, которое не прерывает транзакцию?
\Data Dictionary\Tables\LedgerJournalTable\Methods\validateWrite
\Classes\FormDataSource\validateWrite
\Forms\LedgerJournalTable\Data Sources\LedgerJournalTable\Methods\validateWrite
\Classes\FormDataSource\write
\Forms\LedgerJournalTable\Data Sources\LedgerJournalTable\Methods\write

В validateWrite таблицы вызывается super() который возвращает false. Там еще дальше есть код - он весь проходит до конца. И вот после return false уже больше ничего не выполняется- управление отдается среде. И теперь ttslevel = 1.
Старый 02.11.2021, 10:08   #20  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
validateWrite возвращает false - всё ОК, нормальное поведение.
Тогда непонятно, где вот это происходит.
Цитата:
Поэтому в validateWrite() в super() аксапта поднимает какое то странное исключение с типом Warning.
Цитата:
Проверял - поднимается
исключение типа info, выполнение обрывается, транзакция не откатывается системой
Беда с транзакцией-то откуда? почему ttscommit не выполняется в
X++:
ttsbegin;
super();
journalFormTable.datasourceWritePost();
ttscommit;
Или у вас по непонятным причинам return false в validateWrite не выполняет как раз корректно, и вместо выхода из метода и перехода в следующий - идет передача управления пользовательскому интерфейсу (со все ещё открытой транзакцией)?
Теги
стек вызовов, транзакции

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
ttsbegin и зацикливание While select Perc DAX: Программирование 4 21.11.2014 08:55
Win2008 и вызов методов COM-объектов AndyD DAX: Программирование 13 06.02.2012 15:22
Падает стандартный импорт с ошибкой "Вызов ttscommit без вызова ttsbegin" skof DAX: Администрирование 6 19.01.2012 17:12
dynamics-ax-dev: CLR Errors & ttsbegin/ttscommit Blocks Blog bot DAX Blogs 0 02.11.2010 18:05
ttsbegin ttscommit and changecompany() Volodymyr DAX: Программирование 9 29.08.2008 15:36
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:40.