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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.01.2024, 14:53   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Защита от повреждения типа таблицы в Аксапте 2012 R3
Привет всем.

Вот здесь я описал идею как можно было бы защититься от повреждений типа таблиц в аксапте 2012 R3
После инсталяции Map вдруг cтал Table?!

Попробовал реализовать. Похоже все получилось.
https://github.com/KozlovPavel677/AxTableTypeChangeFix

Идея фикса.
1. Пишем в базе модели функцию (aMRC_axTableType), которая разбирает бинарное поле ModelElementData.Properties и определяет по нему тип табличного объекта. Результат функции:
0 - Unknown
1 - Table
2 - View
3 - Map

2. На табличке ModelElementData в базе модели пишем триггер, который проверяет не поменялся ли для обновляемой таблички результат функции aMRC_axTableType. Если поменялся, то ругаемся и откатываем транзакцию (реально пришлось рубить текущее соединение)

Примерно неделю триггер живет на деве и тесте. Проблем не заметили.
Как тестировали.
Класс ViewTableProps_MRC перебирает все таблички в приложении и для каждой определяет тип таблицы через распаковку бинарного свойства ModelElementData.Properties и сравнивает результа с тем что вернул DictTable.isView() и DictTable.isMap(). Если выявлено несоответствие то пишет в инфолог "ERROR !!!".

Просьба к участникам форума поучаствовать в тестировании, прогнать этот проверочный класс на своих приложениях. Вдруг выявится ошибка в определении типа таблицы. Но мне кажется, что все должно быть нормально. Мы проверяли всеми способами.
За это сообщение автора поблагодарили: sukhanchik (10), Manner (1), Dron AKA andy (5), gl00mie (10).
Старый 29.01.2024, 20:38   #2  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Добрый день!
А в каких случаях происходит "порча" таблиц?
Я пока обнаружил только одно событие (правда, с 99% гарантией) - это построение в пакете перекрестных ссылок. Т.е. если:
- во время построения - программировать
- после построения - программировать.
То высока вероятность, что что-то испортится. Понимания пока правда нет, по какому принципу выбирается объект для "порчи".
Однако этот сценарий замечательно лечится:
- исключением программирования при построении перекрестных ссылок (их можно строить на копии приложения)
- рестартом АОСа после завершения построения ссылок (что в общем-то всегда полезно после выполнения крупного пакетника). На копии - вопрос рестарта вообще не стоит.

В начало и завершение построения ссылок легко можно встроить оповещения при необходимости.
__________________
Возможно сделать все. Вопрос времени
Старый 29.01.2024, 22:59   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Однако этот сценарий замечательно лечится:
Это преувеличение.
Он не замечательно лечится. По моим ощущениям, сильно снижается вероятность проблемы, но совсем она не пропадает. Возможно есть еще какие-то сценарии при которых воспроизводится глюк.

Ну и, в общем-то, зачем workaround, за применением которого нужно постоянно следить, следить за рестартами аоса, итп набором ограничений (причем гарантий опять же нет), если возможен более гарантированный способ закрыть лазейку на уровне SQL.


P.S.
Мне показалось, что еще бывает при глобальной компиляции. Но специально я не выяснял.

Еще пару раз видел похожий глюк - затерлись Primary и Cluster индексы на куче табличке при работе AxBuild и параллельном старте аоса. Это немного из другой серии, но похоже.
Старый 30.01.2024, 09:08   #4  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Это преувеличение.
Он не замечательно лечится. По моим ощущениям, сильно снижается вероятность проблемы, но совсем она не пропадает. Возможно есть еще какие-то сценарии при которых воспроизводится глюк.

Ну и, в общем-то, зачем workaround, за применением которого нужно постоянно следить, следить за рестартами аоса, итп набором ограничений (причем гарантий опять же нет), если возможен более гарантированный способ закрыть лазейку на уровне SQL.


P.S.
Мне показалось, что еще бывает при глобальной компиляции. Но специально я не выяснял.

Еще пару раз видел похожий глюк - затерлись Primary и Cluster индексы на куче табличке при работе AxBuild и параллельном старте аоса. Это немного из другой серии, но похоже.
Про глобальную компиляцию соглашусь, т.к. построение перекрестных ссылок суть есть глобальная компиляция + запись данных в XREF*-таблички.
Не... решение понятное, логичное и т.д.

Однако я со своей стороны перестал наблюдать эту проблему иными действиями:
1. Любая глобальная компиляция "обрамляется" рестартами АОСа - до начала, чтобы сбросить весь кэш. И по окончанию, чтобы "прочистить" память. Просто так обычно компиляция не запускается (всё же не на 5 минут) - поэтому лишний рестарт никому не мешает. Опять-таки - любые запуски регламентных операций делаются в скриптах, поэтому +/- одно действие в скрипте никому не мешает (да и время рестарта АОСа несопоставимо с временем глобальной компиляции / построением перекрестных ссылок)

2. Крайне желательно после построения перекрестных ссылок / глобальной компиляции рестартовать все АОСы (если их было несколько). Опять-таки - на рабочей БД ссылки необязательно строить - их туда можно переносить средствами SQL с отдельной среды, приложение которой является полной копией рабочей.

3. Вообще полезно взять за правило рестартовать АОС раз в сутки на DEV-приложении. Во-первых сбрасывается кэш (поля кто-то добавил и т.д.), во-вторых все разработчики с утра зайдут в заведомо "свежее" приложение.

4. С п.3 можно увязать ежедневную сборку CIL на DEV-приложении (заодно все отчучаются оставлять на ночь ошибки компиляции). Это крайне полезно, т.к. в AX2012 полно объектов, требующих актуального CIL-а. При этом следует обратить внимание, как происходит сборка CIL - в память набирается список классов, т.о. после сборки CIL-а для целей высвобождения памяти лучше сделать рестарт АОСа. А до сборки - рестарт нужен для сброса кэша (отлично увязывается с п.3)

5. Ну и конечно нужно забыть о правках на рабочей базе. Максимум - формы / дизайны SSRS-отчетов.

6. Перекрестные ссылки желательно строить на том приложении, на котором:
- никто не работает
- АОС которого не жалко рестартануть по завершению построения ссылок
А перенести данные ссылок легко можно средствами SQL

В общем - при таком подходе проблема "порчи" таблиц исчезает. Учитывая, что сей подход в целом вынужден применяться в связи с особенностью AX2012 - то в общем-то получается и специального решения проблемы не нужно.
__________________
Возможно сделать все. Вопрос времени
За это сообщение автора поблагодарили: Logger (5), Dron AKA andy (5), gl00mie (5).
Старый 30.01.2024, 12:25   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
В принципе у нас похоже работало, но не во всем. Был сделан отдельный аос для пакетов на деве. Он же обслуживал бизнесконнекторы. На нем же шел сбор перекрестных ссылок. Все резко полегчало. Но иногда все равно случались проблемы.
Возможно потому, что мы не придерживались так строго вашего порядка . Возможно влияла компиляция на всех аосах (инструмент по сбросу кеша, когда по кнопке новые проект импортируется на каждом аосе тем самым прочищая там кеш исполнимого кода, выравнивая кеши без рестарта аосов). Сейчас мы к этому добавили триггер как последнюю контрольную точку. Пока все нормально.

Касательно порядка действий, который вы предлагаете. Мне он кажется достаточно строгим и в то же время сложным, чтобы его легко нарушали на практике. Тут говори не говори : "Сюда ходи, туда не ходи, снег башка попадет, совсем мертвый будешь" - все равно сложно соблюдать столько ограничений. Кто-нибудь да нарушит. Да и нужно ли если теперь есть способ получше ? Мы же триггером сами бинарные недокументированные свойства не пишем, просто следим за ними и рубим транзакции (вместе с соединением к БД), которые собираются пакостить. Достаточно безопасный подход по врачебному принципу "Не навреди".

Кстати, в обычной работе в IDE сбор перекрестных ссылок нередко используется разными утилитами (HK Framework, разные примочки к EditorScripts Открыть в новом окне объект из кода итп) как раз там где идет разработка. Тоже получается может повреждаться тип таблицы ? Вот тебе и дыра.

Последний раз редактировалось Logger; 30.01.2024 в 12:29.
Старый 30.01.2024, 15:48   #6  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
В принципе у нас похоже работало, но не во всем. Был сделан отдельный аос для пакетов на деве. Он же обслуживал бизнесконнекторы. На нем же шел сбор перекрестных ссылок. Все резко полегчало. Но иногда все равно случались проблемы.
Собственно первая грабля - не надо делать несколько АОСов на DEV-приложении. Ибо активная разработка часто требует рестарт АОСа и лишние АОСы - только добавляют проблем. Всякие там бизнес-коннекторы, SSRS-отчеты, Workflow и пакетники удобно отлаживать на отдельном приложении, на котором всегда гарантированно можно собрать CIL.
Т.е. делаем копию DEV -> DEV_CIL и на DEV_CIL уже можно и много АОСов и и всё, что хочешь. Правда надо помнить о том, то разработка в среде, где много АОСов имеет свои проблемы с кэшированием, поэтому для разработки проще, чтобы АОС был один.

Цитата:
Сообщение от Logger Посмотреть сообщение
Возможно потому, что мы не придерживались так строго вашего порядка . Возможно влияла компиляция на всех аосах (инструмент по сбросу кеша, когда по кнопке новые проект импортируется на каждом аосе тем самым прочищая там кеш исполнимого кода, выравнивая кеши без рестарта аосов). Сейчас мы к этому добавили триггер как последнюю контрольную точку. Пока все нормально.
Такой подход успешно работал в AX2009-й и то... вопрос сколько АОСов. Если АОСов под сотню - то ненакомпилируешься.
А в 2012 с появлением CIL такой подход имеет много ограничений (CIL-то не обновляется)

Цитата:
Сообщение от Logger Посмотреть сообщение
Касательно порядка действий, который вы предлагаете. Мне он кажется достаточно строгим и в то же время сложным, чтобы его легко нарушали на практике. Тут говори не говори : "Сюда ходи, туда не ходи, снег башка попадет, совсем мертвый будешь" - все равно сложно соблюдать столько ограничений. Кто-нибудь да нарушит. Да и нужно ли если теперь есть способ получше ? Мы же триггером сами бинарные недокументированные свойства не пишем, просто следим за ними и рубим транзакции (вместе с соединением к БД), которые собираются пакостить. Достаточно безопасный подход по врачебному принципу "Не навреди".
Не.. Вы хорошо решили ту проблему, которая перед Вами стояла - это ж здорово .
Я ж не говорю, что Ваш способ решения плох. Равно как и не предлагаю свой порядок. Просто есть статистика, что применение порядка такого, как у меня - проблем не возникает. А вот почему она не возникает и какой тут "снег башка попадет" - это уж я не знаю. Была бы проблема - пошел бы решать )
Цитата:
Сообщение от Logger Посмотреть сообщение
Кстати, в обычной работе в IDE сбор перекрестных ссылок нередко используется разными утилитами (HK Framework, разные примочки к EditorScripts Открыть в новом окне объект из кода итп) как раз там где идет разработка. Тоже получается может повреждаться тип таблицы ? Вот тебе и дыра.
Опять-таки - тоже из опыта. Утилиты используются, но проблем не возникает. Почему? Не знаю. Может быть из-за того, что ссылки собираются только по одному объекту.
Более того - я люблю проект компилировать с обновлением перекрестных ссылок. И тоже проблем не возникает.
Я могу лишь констатировать факт, что если я соберу в пакетнике перекрестные ссылки на всем приложении и начну после этого программировать без рестарта АОСа - то у меня скорее всего какой-то объект действительно разломается. "Но это не точно" (с)
__________________
Возможно сделать все. Вопрос времени
Старый 08.05.2024, 19:07   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Я могу лишь констатировать факт, что если я соберу в пакетнике перекрестные ссылки на всем приложении и начну после этого программировать без рестарта АОСа - то у меня скорее всего какой-то объект действительно разломается. "Но это не точно" (с)
Сегодня триггер ночью отработал на сборе перекрестных ссылок. Причем поймал проблему не после завершения сбора, а в середине процесса.
Похоже проблема носит вероятностный характер и вам просто везло.

Правда у нас сбор ссылок распараллелен в примерно 10 потоков (чтобы собирал за 3 часа, а не за 12-13). Возможно это тоже влияет на воспроизводимость бага.
За это сообщение автора поблагодарили: sukhanchik (4).
Старый 08.05.2024, 22:12   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Сегодня триггер ночью отработал на сборе перекрестных ссылок. Причем поймал проблему не после завершения сбора, а в середине процесса.
Похоже проблема носит вероятностный характер и вам просто везло.

Правда у нас сбор ссылок распараллелен в примерно 10 потоков (чтобы собирал за 3 часа, а не за 12-13). Возможно это тоже влияет на воспроизводимость бага.
Интересный случай, спасибо. Равно, как и многопоточка в части сбора перекрестных ссылок.
Но я тут склонен грешить на многопоточку. Дело в том, что этот глюк 100% появляется, когда в память кэшируется "то, что не надо". А потоки, когда работают параллельно... наверняка же работают в одном АОСе и имеют общий кэш.

А 12-13 часов сбора перекрестных ссылок - это последствия виртуализации сервера БД А если на нём еще и Windows Server 2016 (вместо Windows Server 2012 R2) стоит - то... это тоже еще влияет.

У нас ссылки собираются 8 часов в одном потоке (сервер БД невиртуализирован), но я нашел обходной путь в виде построения их на копии с последующим переносом XREF*-табличек средствами SQL на нужную БД.

Т.е. выполняются такие шаги:
1. Копируется приложение + БД DEV -> DEVCopy
2. Делается сборка полного CIL на DEVCopy.
3. Если сборка CIL прошла неуспешно - процесс завершается. Тут уже требуется вмешательство человека
4. Запускается (на AOS-сервере) клиент АХ с параметром xrefall (см класс SysStartupCmdXReference). Этот клиент ставит построение ссылок в пакет, а сам лишь мониторит завершение этого пакета.
5. По завершению работы этого клиента (а он завершится тогда, когда завершится пакетник) рестартуется АОС DEVCopy (для профилактики; для целей перекрестных ссылок этого делать не требуется)
6. Переливаются XREF* таблички из БД DEVCopy в БД DEV

По-хорошему, после этого нужно бы остановить АОС DEV и выполнить коррекцию счетчиков RecId в табличках XREF* (иначе компиляция проекта с включенной галкой Перекрестные ссылки может привести к ошибкам), но честно признаюсь - я этого не делаю, ибо не хочется рестартовать АОС, а пока заявок на эту проблему не поступало

Все описанные действия выполняются в скрипте Powershell и поставлены в шедулер (скрипт срабатывает по расписанию).
Этот же скрипт (но с другими параметрами приложения) отрабатывает для PROD-приложения после релиза (но там без копирования в БД-копию; плюс скрипт я запускаю вручную при условии успешности релиза).

Ну и... административно со временем все привыкли к 22:00 (время рестарта АОСа DEV для сборки CIL + снятия копии для построения перекрестных ссылок) не оставлять ошибок компиляции на DEV-приложении для автоматического рестарта АОСа со сборкой полного CIL-а.
Исключения конечно случаются - куда ж без них.
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 08.05.2024 в 22:16.
За это сообщение автора поблагодарили: Logger (15).
Старый 09.05.2024, 07:40   #9  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,163 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
По-хорошему, после этого нужно бы остановить АОС DEV и выполнить коррекцию счетчиков RecId в табличках XREF* (иначе компиляция проекта с включенной галкой Перекрестные ссылки может привести к ошибкам), но честно признаюсь - я этого не делаю, ибо не хочется рестартовать АОС, а пока заявок на эту проблему не поступало
Это просто мы терпеливые.
На самом деле часто после копирования перекрестных ссылок на некоторых действиях Акса кричит, что не может вставить запись в XRef... Например, при просмотре таблиц при помощи Table browser.
За это сообщение автора поблагодарили: sukhanchik (3).
Старый 09.05.2024, 21:58   #10  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Это просто мы терпеливые.
На самом деле часто после копирования перекрестных ссылок на некоторых действиях Акса кричит, что не может вставить запись в XRef... Например, при просмотре таблиц при помощи Table browser.
Странно конечно - зачем Аксе требуется создавать запись в Xref при открытии Table Browser (не встречал такого), но... ок, можно и этот момент исправить. Просто, к сожалению, табличку SystemSequences можно менять только при остановленном АОСе. И если вдруг обновление ссылок закончилось в "рабочее" время - то рестарт АОСа без предупреждения может напрячь...
__________________
Возможно сделать все. Вопрос времени
Старый 13.05.2024, 15:16   #11  
michel1971 is offline
michel1971
Участник
 
77 / 78 (3) ++++
Регистрация: 14.01.2011
Вместо рестарта аоса, можно попробовать дернуть \Classes\ReleaseUpdateBulkCopyDB\flushNextRecIdForTable
За это сообщение автора поблагодарили: Logger (3), sukhanchik (12).
Старый 14.05.2024, 00:06   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Странно конечно - зачем Аксе требуется создавать запись в Xref при открытии Table Browser (не встречал такого), но...
Может из-за этого ?
Открыть в новом окне объект из кода
За это сообщение автора поблагодарили: sukhanchik (3).
Старый 14.05.2024, 07:19   #13  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Конкретно этого кода не нашел на том приложении, на котором искал, но ... тут само действие хотя бы объяснимо - тут сама функция концептуально построена на генерации записей в XREFREFERENCES.
Но Table Browser тут точно ни при чем.

Попробую сначала решение со сбросом кэша...

Спасибо за версии!
__________________
Возможно сделать все. Вопрос времени
Старый 14.05.2024, 07:52   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Конкретно этого кода не нашел на том приложении, на котором искал
А чего его искать. Добавьте логирование с записью стека вызовов на вставке в xRef* таблички, пропуская это действие для юзера под которым крутится пакет. Оно все само найдет.
За это сообщение автора поблагодарили: sukhanchik (4).
Старый 14.05.2024, 08:14   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от michel1971 Посмотреть сообщение
Вместо рестарта аоса, можно попробовать дернуть \Classes\ReleaseUpdateBulkCopyDB\flushNextRecIdForTable
О! Не знал про этот метод.

А нам пришлось свое изобретать.
Вот пример метода
(он кроме сброса кешей двигает счетчик RecId, чтобы значения гарантированно не пересеклись. Это пришлось делать, потому что по непонятной пока причине счетчики пересекались после переноса бекапа из рабочей на тестовое окружение. Такое ощущение что пока снимается бекап с рабочей (часа 2 занимает), в бекап в начале процесса попадают одни значения systemSequence, которые к моменту окончания бекапа уже становились неактуальными, так что в некоторых табличках появлялись записи с бОльшими значениями RecId и потом на тестовом окружении ругалась на конфликт уникальности по RecId при создании записи)
X++:
public void processRecIdSequense(TableId _tableId)
{
    systemSequence      systemSequence;

    SystemSequences     systemSequences;
    Common              common;

    void reserve(int numers)
    {
        systemSequence = new systemSequence();
        systemSequence.suspendRecIds(_tableId);
        systemSequence.flushValues(_tableId);
        con2Str([systemSequence.reserveValues(numers, _tableId)]);
        systemSequence.removeRecIdSuspension(_tableId);
    }
    ;

    setPrefix("-");

    if (curext() != "dat")
    {
        throw error("Запуск надо делать в компании dat");
    }

    setPrefix(tableId2name(_tableId));
    common = new DictTable(_tableId).makeRecord();
    common.RecId = SysDictTable::maxRecId_MRC(_tableId);

    select crossCompany systemSequences
        where   systemSequences.Name == "SEQNO"
            &&  systemSequences.Id   == -1
            &&  systemSequences.DataAreaId == 'dat'
            &&  systemSequences.TabId == _tableId;

    if (!systemSequences)
    {
        reserve(1);
        select crossCompany systemSequences
            where   systemSequences.Name == "SEQNO"
                &&  systemSequences.Id   == -1
                &&  systemSequences.DataAreaId == 'dat'
                &&  systemSequences.TabId == _tableId;
    }

    if (!systemSequences)
    {
        this.info(0, "Не найдена запись в systemSequences", true);
        return;
    }

    if (systemSequences.NextVal <= common.RecId)
    {
        this.info(
            1,
            strFmt("Исправляем номерную серию. Был номер %1, стал %2. Разница %3",
                systemSequences.NextVal,
                common.RecId + 1,
                common.RecId + 1 - systemSequences.NextVal
            ),
            true);

        // changeCompany ("dat")
        {
            systemSequences = null;

            ttsBegin;

            new SkipAOSValidationPermission().assert();
            select pessimisticLock systemSequences
                where   systemSequences.Name == "SEQNO"
                    &&  systemSequences.Id   == -1
                    &&  systemSequences.DataAreaId == 'dat'
                    &&  systemSequences.TabId == _tableId;

            systemSequences.skipTTSCheck(true);
            systemSequences.skipDatabaseLog(true);
            systemSequences.selectForUpdate(true);

            if (systemSequences &&
                systemSequences.NextVal <= common.RecId)
            {
                systemSequences.NextVal = common.RecId + 1;
                systemSequences.update();
            }
            ttsCommit;

            CodeAccessPermission::revertAssert();
        }
    }

    reserve(5001);

    this.info(1, "Ok", true);
}
X++:
public static server RecId maxRecId_MRC(TableId _tableId)
{
    SysDictTable                    sysDictTable;
    ResultSet                       resultSet;
    Statement                       statement;

    str                             sqlQuery;

    RecId                           ret;
    ;

    sysDictTable = SysDictTable::newTableId(_tableId);
    sqlQuery = strFmt(@"select max(RecId) from %1", sysDictTable.name(DbBackend::Sql));

    if (sqlQuery)
    {
        new SqlStatementExecutePermission(sqlQuery).assert();

        try
        {
            //BP Deviation documented
            statement = new Connection().createStatement();
            resultSet = statement.executeQuery(sqlQuery);
            if (resultSet.next())
            {
                ret = resultSet.getInt64(1);
            }
        }
        catch
        {
            error("Was errors");
        }
    }

    return ret;
}
А в стандарте так
X++:
public static void flushNextRecIdForTable(TableId _tableId)
{
    systemSequence systemSequence = new systemSequence();

    systemSequence.suspendRecIds(_tableId);
    systemSequence.flushValues(_tableId);
    systemSequence.removeRecIdSuspension(_tableId);
}

Последний раз редактировалось Logger; 14.05.2024 в 08:35.
Старый 14.05.2024, 08:24   #16  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
А 12-13 часов сбора перекрестных ссылок - это последствия виртуализации сервера БД А если на нём еще и Windows Server 2016 (вместо Windows Server 2012 R2) стоит - то... это тоже еще влияет.

У нас ссылки собираются 8 часов в одном потоке (сервер БД невиртуализирован), но я нашел обходной путь в виде построения их на копии с последующим переносом XREF*-табличек средствами SQL на нужную БД.
Интересно. Не знал про такой выигрыш от 2012-й винды по сравнению с 2016-й. Мы как-то сразу с 2008-й на 2016-ю перескочили, а затем на 2019.

А что скажете про 2019-ю ?
У меня, по ощущениям, она шустрее 2016-й - просто если оценивать отзывчивость интерфейса аксапты, когда клиента аксапты открываешь на сервере с 2019-й и там же служба аоса хостится. Но вот при сборе перекрестных ссылок не заметил разницы. Возможно, все оптимизации и ускорения 2019-й винды съела виртуализация SQL.
Старый 14.05.2024, 08:43   #17  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Интересно. Не знал про такой выигрыш от 2012-й винды по сравнению с 2016-й. Мы как-то сразу с 2008-й на 2016-ю перескочили, а затем на 2019.

А что скажете про 2019-ю ?
У меня, по ощущениям, она шустрее 2016-й - просто если оценивать отзывчивость интерфейса аксапты, когда клиента аксапты открываешь на сервере с 2019-й и там же служба аоса хостится. Но вот при сборе перекрестных ссылок не заметил разницы. Возможно, все оптимизации и ускорения 2019-й винды съела виртуализация SQL.
Ничего не скажу - не экспериментировал. Про 2012R2 тоже не знал - коллеги подсказали, а я проверил на тестовом стенде. Но тут вопрос не в скорости самой винды как таковой, а в оптимизации обращения к дискам (и прочим ресурсам операционной системы) от SQL Server. Т.е. SQL Server обращается к виндовым библиотечкам и в случае 2012R2 эти обращения происходят шустрее (для SQL 2016), нежели для винды 2016
__________________
Возможно сделать все. Вопрос времени
Старый 14.05.2024, 08:50   #18  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Это просто мы терпеливые.
На самом деле часто после копирования перекрестных ссылок на некоторых действиях Акса кричит, что не может вставить запись в XRef... Например, при просмотре таблиц при помощи Table browser.
Нашел барабашку. Оказывается в стандарте всё хорошо . Но если пользоваться всякими утилитками, привнесенными извне - то да, в них могут быть и такие сюрпризы, как построение перекрестных ссылок при просмотре обозревателя таблиц )). Я то этим не пользовался никогда - вот и не замечал проблем

Нажмите на изображение для увеличения
Название: чч.png
Просмотров: 133
Размер:	21.6 Кб
ID:	13646
__________________
Возможно сделать все. Вопрос времени
Старый 14.05.2024, 08:52   #19  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,303 / 3533 (124) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
А чего его искать. Добавьте логирование с записью стека вызовов на вставке в xRef* таблички, пропуская это действие для юзера под которым крутится пакет. Оно все само найдет.
Спасибо. Эта идея помогла решить другую задачу )).
Конкретно место всё-таки нашел и там (конкретно в моем случае) уже "по-правильному" исправлено
__________________
Возможно сделать все. Вопрос времени
Старый 14.05.2024, 09:15   #20  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,928 / 3227 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Нашел барабашку.
Ха, у нас тоже на HK Framework проявлялось. Поэтому и нашел, когда занялся оптимизацией.
Теги
ax2012, ax2012r2, ax2012r3, map, modelelementdata, table, view

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Sumit Potbhare: AX 2012 R3 | Statement Posting| Part IV: Hotfixes Blog bot DAX Blogs 0 23.06.2017 14:11
stoneridgesoftware: Part I: Configuring the Dynamics AX 2012 R3 Entity Store Blog bot DAX Blogs 0 27.04.2017 12:11
dynamicsaxse: Announcing Cumulative Update 12 for Microsoft Dynamics AX 2012 R3 Blog bot DAX Blogs 0 22.11.2016 13:11
axsa: Extensibility in Dynamics AX 2012 R3 CU8 (CRT, RetailServer, MPOS) Part 2 – New data entity Blog bot DAX Blogs 0 21.05.2015 01:19
amer-ax: It was a great day! Blog bot DAX Blogs 3 29.12.2012 01:02

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

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

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