07.10.2021, 15:31 | #1 |
Участник
|
Как найти вызов 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 |
Участник
|
Цитата:
Попробуйте в параметрах AOS включить точки останова на уровне сервера |
|
11.10.2021, 05:08 | #4 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Поймать стек вызова у долгой транзакции.
Попробуйте в параметрах AOS включить точки останова на уровне сервера Кстати заметил разницу при вызове xSession::xppCallStack() на клиенте и на сервере. При вызове с клиента иногда более информативно получается, но в моей проблеме не помогло. Точки останова само собой включены. Попробую еще модальным окном остановить работу пользователя. Чтобы он позвонил и сказал что он нажимал в последний раз.. А нет, так подумываю уже о временной возможности тотальной замены всех ttsbegin на вызов ttsbegin с серверной процедуры) |
|
11.10.2021, 05:18 | #5 |
Участник
|
От отсутствия вариантов попробовал и представленный анализатор. Предупреждений он навалил достаточно конечно. Но там все не существенно.
Ошибок - 95% не справился с методами в которых есть синтаксис clr.(обработка под 3-ку делалась) А остальные десяток мест из кого-то заброшенного функционала который уже нигде и никем у нас не используется. Выявился один рабочий отчет с return между tts. Но по факту оказалось, что тоже не рабочее место.. |
|
11.10.2021, 07:03 | #6 |
Участник
|
В аксапте была табличка лога sysutilelementslog или как то так.
Там логировалис используемые юзером формы и очеты. Несложной доработкой можно обобщить до классов. Тем самым еще сузить область поисков. |
|
11.10.2021, 08:21 | #7 |
Участник
|
Цитата:
Несложной это какой? за созданием форм слежение из \xClassFactory\formRunClass сделано. Как бэ системой поддерживается.. А класс на что зацепится? |
|
11.10.2021, 09:46 | #8 |
Участник
|
Я в 4-ку перетаскивал из 2009-й
Еще добавил тут \Classes\RunBase\new \Classes\ClassFactory\createClass помогает для Runbase а также для всего что по менюитем запускается. Конечно это не все классы охватывает но очень многое. Также можно вот это применить это одна из идей, которую я хочу пропихнуть в АХ 2012. Ошибка с транзакциями! |
|
01.11.2021, 12:25 | #9 |
Участник
|
В итоге xSession::xppCallStack() оказался совершенно бесполезным в поиске проблемы.
Самым простым и действенным получилось в onEventGoingIdle показать модальное окно после проверки ttsLevel. С третьей попытки пользователь таки прочитал сообщение и позвонил) Проблема была на форме LedgerJournalTable. Ктото у нас на modified одного из полей сделал LedgerJournalTable_ds.write(). А во write на форме: X++: ttsbegin; super(); journalFormTable.datasourceWritePost(); ttscommit; По мне write() в коде не выглядит каким то уж криминалом. А вот реакция системы с бросанием кода, но без отката транзакции - непонятно.. Предполагается что? Написать еще дополнительно проверку validateWite перед wite? |
|
|
За это сообщение автора поблагодарили: S.Kuskov (5). |
01.11.2021, 13:32 | #10 |
Участник
|
|
|
01.11.2021, 14:25 | #11 |
Участник
|
Да все это выглядит как ересь. Затыкание багов(фитчей) ядра. По мне 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 |
Участник
|
Не понятно, где тут баг ядра, если источник проблемы в том что-то у вас в modified написал .write() - что делать, в целом, не стоит никогда.
|
|
01.11.2021, 15:11 | #13 |
Участник
|
Цитата:
Принципиальной разницы нет - modified, clicked... Почему DS.executeQuery() можно написать, а DS.write() нельзя? DS.write() незримо написан на любой кнопке со свойством SaveRecord=Yes Какие нерушимые принципы нарушены таким вызовом? Надо пояснять.. а так это блабла.. извините) |
|
01.11.2021, 15:30 | #14 |
Участник
|
Это, конечно, оффтоп, но на мой взгляд вешать логику сохранения ЛЮБОЙ (не обязательно текущей) записи в событие modified поля - это отвратительный дизайн.
Хуже только вешать в событии validateField. |
|
01.11.2021, 16:11 | #15 |
Участник
|
У меня нет претензий к тому чтобы считать, что это плохой дизайн. У меня претензия к тому что вы очень быстро связали мою изначальную ошибку незакрытого ttsBegin с якобы плохим дизайном. И прикопались к modified.. такая проблема выскочит при программном вызове DS.write() из любого места.
|
|
01.11.2021, 23:15 | #16 |
Участник
|
|
|
02.11.2021, 07:25 | #17 |
Участник
|
Цитата:
исключение типа 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(); } |
|
|
За это сообщение автора поблагодарили: sukhanchik (2). |
02.11.2021, 08:12 | #18 |
Участник
|
Цитата:
поднимается исключение типа info
|
|
02.11.2021, 09:37 | #19 |
Участник
|
Цитата:
\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 |
Участник
|
validateWrite возвращает false - всё ОК, нормальное поведение.
Тогда непонятно, где вот это происходит. Цитата:
Поэтому в validateWrite() в super() аксапта поднимает какое то странное исключение с типом Warning.
Цитата:
Проверял - поднимается
исключение типа info, выполнение обрывается, транзакция не откатывается системой X++: ttsbegin; super(); journalFormTable.datasourceWritePost(); ttscommit; |
|
Теги |
стек вызовов, транзакции |
|
|