27.01.2024, 14:53 | #1 |
Участник
|
Защита от повреждения типа таблицы в Аксапте 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 |
Administrator
|
Добрый день!
А в каких случаях происходит "порча" таблиц? Я пока обнаружил только одно событие (правда, с 99% гарантией) - это построение в пакете перекрестных ссылок. Т.е. если: - во время построения - программировать - после построения - программировать. То высока вероятность, что что-то испортится. Понимания пока правда нет, по какому принципу выбирается объект для "порчи". Однако этот сценарий замечательно лечится: - исключением программирования при построении перекрестных ссылок (их можно строить на копии приложения) - рестартом АОСа после завершения построения ссылок (что в общем-то всегда полезно после выполнения крупного пакетника). На копии - вопрос рестарта вообще не стоит. В начало и завершение построения ссылок легко можно встроить оповещения при необходимости.
__________________
Возможно сделать все. Вопрос времени |
|
29.01.2024, 22:59 | #3 |
Участник
|
Это преувеличение.
Он не замечательно лечится. По моим ощущениям, сильно снижается вероятность проблемы, но совсем она не пропадает. Возможно есть еще какие-то сценарии при которых воспроизводится глюк. Ну и, в общем-то, зачем workaround, за применением которого нужно постоянно следить, следить за рестартами аоса, итп набором ограничений (причем гарантий опять же нет), если возможен более гарантированный способ закрыть лазейку на уровне SQL. P.S. Мне показалось, что еще бывает при глобальной компиляции. Но специально я не выяснял. Еще пару раз видел похожий глюк - затерлись Primary и Cluster индексы на куче табличке при работе AxBuild и параллельном старте аоса. Это немного из другой серии, но похоже. |
|
30.01.2024, 09:08 | #4 |
Administrator
|
Цитата:
Сообщение от Logger
Это преувеличение.
Он не замечательно лечится. По моим ощущениям, сильно снижается вероятность проблемы, но совсем она не пропадает. Возможно есть еще какие-то сценарии при которых воспроизводится глюк. Ну и, в общем-то, зачем workaround, за применением которого нужно постоянно следить, следить за рестартами аоса, итп набором ограничений (причем гарантий опять же нет), если возможен более гарантированный способ закрыть лазейку на уровне SQL. P.S. Мне показалось, что еще бывает при глобальной компиляции. Но специально я не выяснял. Еще пару раз видел похожий глюк - затерлись Primary и Cluster индексы на куче табличке при работе AxBuild и параллельном старте аоса. Это немного из другой серии, но похоже. Не... решение понятное, логичное и т.д. Однако я со своей стороны перестал наблюдать эту проблему иными действиями: 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 |
Участник
|
В принципе у нас похоже работало, но не во всем. Был сделан отдельный аос для пакетов на деве. Он же обслуживал бизнесконнекторы. На нем же шел сбор перекрестных ссылок. Все резко полегчало. Но иногда все равно случались проблемы.
Возможно потому, что мы не придерживались так строго вашего порядка . Возможно влияла компиляция на всех аосах (инструмент по сбросу кеша, когда по кнопке новые проект импортируется на каждом аосе тем самым прочищая там кеш исполнимого кода, выравнивая кеши без рестарта аосов). Сейчас мы к этому добавили триггер как последнюю контрольную точку. Пока все нормально. Касательно порядка действий, который вы предлагаете. Мне он кажется достаточно строгим и в то же время сложным, чтобы его легко нарушали на практике. Тут говори не говори : "Сюда ходи, туда не ходи, снег башка попадет, совсем мертвый будешь" - все равно сложно соблюдать столько ограничений. Кто-нибудь да нарушит. Да и нужно ли если теперь есть способ получше ? Мы же триггером сами бинарные недокументированные свойства не пишем, просто следим за ними и рубим транзакции (вместе с соединением к БД), которые собираются пакостить. Достаточно безопасный подход по врачебному принципу "Не навреди". Кстати, в обычной работе в IDE сбор перекрестных ссылок нередко используется разными утилитами (HK Framework, разные примочки к EditorScripts Открыть в новом окне объект из кода итп) как раз там где идет разработка. Тоже получается может повреждаться тип таблицы ? Вот тебе и дыра. Последний раз редактировалось Logger; 30.01.2024 в 12:29. |
|
30.01.2024, 15:48 | #6 |
Administrator
|
Цитата:
Т.е. делаем копию DEV -> DEV_CIL и на DEV_CIL уже можно и много АОСов и и всё, что хочешь. Правда надо помнить о том, то разработка в среде, где много АОСов имеет свои проблемы с кэшированием, поэтому для разработки проще, чтобы АОС был один. Цитата:
Сообщение от Logger
Возможно потому, что мы не придерживались так строго вашего порядка . Возможно влияла компиляция на всех аосах (инструмент по сбросу кеша, когда по кнопке новые проект импортируется на каждом аосе тем самым прочищая там кеш исполнимого кода, выравнивая кеши без рестарта аосов). Сейчас мы к этому добавили триггер как последнюю контрольную точку. Пока все нормально.
А в 2012 с появлением CIL такой подход имеет много ограничений (CIL-то не обновляется) Цитата:
Сообщение от Logger
Касательно порядка действий, который вы предлагаете. Мне он кажется достаточно строгим и в то же время сложным, чтобы его легко нарушали на практике. Тут говори не говори : "Сюда ходи, туда не ходи, снег башка попадет, совсем мертвый будешь" - все равно сложно соблюдать столько ограничений. Кто-нибудь да нарушит. Да и нужно ли если теперь есть способ получше ? Мы же триггером сами бинарные недокументированные свойства не пишем, просто следим за ними и рубим транзакции (вместе с соединением к БД), которые собираются пакостить. Достаточно безопасный подход по врачебному принципу "Не навреди".
Я ж не говорю, что Ваш способ решения плох. Равно как и не предлагаю свой порядок. Просто есть статистика, что применение порядка такого, как у меня - проблем не возникает. А вот почему она не возникает и какой тут "снег башка попадет" - это уж я не знаю. Была бы проблема - пошел бы решать ) Цитата:
Сообщение от Logger
Кстати, в обычной работе в IDE сбор перекрестных ссылок нередко используется разными утилитами (HK Framework, разные примочки к EditorScripts Открыть в новом окне объект из кода итп) как раз там где идет разработка. Тоже получается может повреждаться тип таблицы ? Вот тебе и дыра.
Более того - я люблю проект компилировать с обновлением перекрестных ссылок. И тоже проблем не возникает. Я могу лишь констатировать факт, что если я соберу в пакетнике перекрестные ссылки на всем приложении и начну после этого программировать без рестарта АОСа - то у меня скорее всего какой-то объект действительно разломается. "Но это не точно" (с)
__________________
Возможно сделать все. Вопрос времени |
|
Теги |
ax2012, ax2012r2, ax2012r3, map, modelelementdata, table, view |
|
|