Показать сообщение отдельно
Старый 16.01.2017, 18:18   #20  
online
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от ice Посмотреть сообщение
Все таки проблема не в синхронизации. Только что добавил поле в дочернюю таблицу, синхронизировал обе таблицы, добавил поле на форму. открываю форму через рабочую область, поле отображается как "не извлечено", открываю таблицу браузером таблиц, редактирую поле в нескольких записях, все сохранилось. открываю форму, картина все та же. открываю форму через АОТ, поле отобразилось правильно

ПС мне вот интересно, у меня у одного такая проблема или еще никто не пробовал добавлять поля в Ax2012?
Привет. Мы поймали багу на обычной табличке (без наследования).
Наследование ни при чем.

Как воспроизводить :
1. Берем, создаем табличку (для определенности AAA).
2. Cоздаем в ней строковое поле TEST.
(Если кому-то лень, то можно импортировать прилагаемый XPO. Только тогда надо удалить в импортированной табличке поле TEST2 и перестартовать аос)
3. Синхронизируем табличку.
4. (опциональный пункт и на воспроизводимость бага не влияет) - настраиваем логирование SysDataBaseLog по табличке AAA
5. Включаем логирование всех SQL запросов (этот пункт опять же не влияет на воспроизводимость бага, но позволяет увидеть проблему со всей очевидностью)
6. Открываем обозреватель таблички. Создаем запись. На SQL уйдет запрос примерно такого вида :
Цитата:
Оператор SQL: (AAA) INSERT INTO AAA (TEST,MODIFIEDDATETIME,MODIFIEDBY,CREATEDDATETIME,CREATEDBY,RECVERSION,PARTITION,RECID) VALUES (?,?,?,?,?,?,?,?) [Идентификатор=105315, Использовано повторно=Нет]
7. Открываем еще примерно 5 штук обозревателей таблицы и в каждом создаем запись (достаточно и одного, но для надежности лучше 5. У меня получалось воспроизвести баг с одним дополнительно открытым обозревателем. Так что всего было 2 обозревателя открыто)
8. Создаем в табличке новое строковое поле TEST2.
9. Синхронизируемся.
10. Открываем обозреватель табличек. Создаем запись, заполняя какое-то значение для поля TEST2.
С большой вероятностью уйдет запрос такого вида
Цитата:
Оператор SQL: (AAA) INSERT INTO AAA (TEST,MODIFIEDDATETIME,MODIFIEDBY,CREATEDDATETIME,CREATEDBY,RECVERSION,PARTITION,RECID) VALUES (?,?,?,?,?,?,?,?) [Идентификатор=33086, Использовано повторно=Да]
т.е. в нем совсем не будет упомянуто поле TEST2 !!!

Если все же ушел корректный перечень полей на вставке, то можно открыть еще 1-2 обозревателя и повторить в нем действия п.10
Должен уйти кривой запрос на вставку в котором поле TEST2 не упомянуто.
Соответственно, в базе будет создана запись с пустым (дефолтным) значением.

Пробуем перехитрить аксапту.
Закрываем клиента.
Заходим снова.
Открываем обозреватель таблички AAA.
Все ок.
Создаем запись - тоже все ок. На вставку уходит оба поля (TEST и TEST2)

Все хорошо ?
Как бы не так!

Открываем еще один обозреватель таблицы.
Теперь внимательнее. С вероятностью примерно 10 % - в БД уйдет кривой запрос на выборку, без поля TEST2. Например такой :
Цитата:
Оператор SQL: (AAA) SELECT T1.TEST,T1.MODIFIEDDATETIME,T1.MODIFIEDBY,T1.CREATEDDATETIME,T1.CREATEDBY,T1.RECVERSION,T1.PARTITION,T1.RECID FROM AAA T1 WHERE (PARTITION=?) ORDER BY T1.RECID OPTION(FAST 19) [Идентификатор=33638, Использовано повторно=Да]
(в запросе нет поля TEST2)

При этом в обозревателе в столбце для TEST2 будет написано "Не извлечено" - как раз тот случай который ICE описал. Если попробовать наложить какой нибудь фильтр или отсортировать записи то с вероятностью 99 % уйдет запрос с полей TEST2 в перечне полей и все будет ок.

Далее. Создаем в новом обозревателе таблиц новую запись. Заполняем поля непустыми значениями и видим в логе запросов что с вероятностью 99 % в перечне полей на вставку нет поля TEST2.
Открываем еще один обозреватель таблиц - повторяем наши действия - то же самое.
С очень высокой вероятностью идет запрос
Цитата:
Оператор SQL: (AAA) INSERT INTO AAA (TEST,MODIFIEDDATETIME,MODIFIEDBY,CREATEDDATETIME,CREATEDBY,RECVERSION,PARTITION,RECID) VALUES (?,?,?,?,?,?,?,?) [Идентификатор=33086, Использовано повторно=Да]
вместо запроса
Цитата:
Оператор SQL: (AAA) INSERT INTO AAA (TEST,TEST2,MODIFIEDDATETIME,MODIFIEDBY,CREATEDDATETIME,CREATEDBY,RECVERSION,PARTITION,RECID) VALUES (?,?,?,?,?,?,?,?) [Идентификатор=XXXX, Использовано повторно=Да]
При этом после вставки обозреватель таблички отображает введенное нами значение в поле TEST2 как будто оно вставлено в табличку. Но реально в SQL оно имеет пустое, дефолтное значение. В этом легко убедиться если посмотреть в базу средствами SQL или в том же обозревателе перечитать запись. Если посмотреть историю изменения таблички (для этого мы и включали логирование SysDataBaseLog), то видно что там на вставке ядро думало что поле TEST2 существует в базе и мы его заполняем, т.е. в метод Application.logInsert() ядро прислало корректный перечень значений, а поломка идет где-то дальше - уже на этапе формирования SQL запроса.

В общем, складывается ощущение что в Аосе для каждой таблички есть пул объектов содержащий перечень ее полей (перечень курсоров ?) И при выполнении запроса ядро хватает первую попавшийся элемент из этого пула и использует для формирования запроса. Поэтому с некоторой вероятностью как для чтения так и для вставки запрос может получиться нормальным, а может содержать неверный набор полей. Почему то, когда я тестировал, то у меня вероятность воспроизведения глюка при вставке записи была на порядок выше чем при чтении. При этом во всех случаях когда в запроса было написано "Использовано повторно=Нет" - то глюка не было. А когда был глюк то для него было "Использовано повторно=Да"
Мое предположение про пул объектов это только догадка, основанная на наблюдениях за системой.
(Когда игрался с воспроизведениям бага и создавал еще и поле TEST3, удалось достичь смешной ситуации когда из под одной сессии было открыто 3 обозревателя таблички. У всех в гриде были видны и доступны все поля, а на вставку у первого обозревателя уходили поля TEST, TEST2, TEST3
у второго TEST, TEST2,
а у третьего только TEST. В общем полный расколбас был)
Отдельно обращаю внимание на то, что не только обозреватели таблиц переоткрывались, но сам клиент аксапты перестартовывался после добавления полей ! Причем пакость еще в том что первый обозреватель может нормально открыться и ты уже думаешь что все ок и все кеши прочистились. А открываешь второй, третий и там лезет баг.
------------------------------------------------


В чем основной вопрос поста:
1. Как лечить указанный баг ?

Мне пока удалось только перестартом АОСа. Но это очень неудобно в случае когда еще кто-то сидит и кодирует на аосе.
Да даже если никого нет на аосе - неудобно все закрывать ради перестарта аоса. (Ведь как обычно пишем - покодировали, сразу потестили немного - проверили все ли ок - и не хочется все закрывать и рестартовать аос - это неудобно)
Пробовал также (ничего не помогло):
а. делать синхронизацию.
б. сбрасывать кеши на клиенте и аосе
в. Стандартный финт compile node, refresh node, compile node, который успешно помогал прочищать кеш аоса в 2009-й - здесь не помогает.

Есть ли какой то способ прочистить пул объектов с перечнем полей, не перезагружая аос ?


2. Может быть баг уже исправлен в каком то очередном релизе и нужно просто поставить свежий билд ? Кто-нибудь в курсе, с какой версии исправлено ?
У нас версия ax 2009 R3 ( билд 6.3.2000.4755 Axapta 2012 R3 Cumulative Update 9+)


3. Как дальше жить ?
Вложения
Тип файла: xpo Table_AAA_2017_01_16_18_10_DEV_SAPPWMS01_2712.xpo (1.4 Кб, 733 просмотров)

Последний раз редактировалось Logger; 16.01.2017 в 18:39. Причина: опечатки