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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.03.2009, 14:12   #1  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Баг inventTable
На всякий случай напишу все подробно.
В методе InventTable.insert() super() обрамлен транзакцией.
Есть у меня класс (от RunBaseBatch), в котором суть метода run() примерно такова:
X++:
try
{
ttsbegin;

while ()
{
this.process(container);
}

ttscommit;
}
catch
{
throw error();
}
Метод process(container) переопределен в наследниках этого класса.
В одном из таких классов происходит заполнение InventTable:
X++:
void process(container)
{
// ....

inventTable.insert();

if (- )
 throw error();

//....
}
Изначально InventTable пуста. После того, как отработает этот throw, возникает следующая ситуация. Запрос
X++:
select firstonly inventTable
where inventTable.ItemId == "Первое значение в имп. файле";
Возращает, невставленную на самом деле, запись. Так как throw отработал, то запись в базу не попадает. Это можно увидеть, сделав прямой запрос в базу.
Что удивительно:
X++:
select firstonly inventTable;
тоже ничего не возвращает.

Первый запрос (с условием) начинает нормально работать только если перезагрузить аос. Как это исправить?
Старый 19.03.2009, 14:25   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Спасибо.
Добавил к теме теги "Баг", "ошибка".

Цитата:
Сообщение от Eldar9x Посмотреть сообщение
На всякий случай напишу все подробно.
а в какой версии проявляется?
__________________
полезное на axForum, github, vk, coub.
Старый 19.03.2009, 14:27   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
Первый запрос (с условием) начинает нормально работать только если перезагрузить аос. Как это исправить?
Какие параметры кэширования у вас установлены для этой таблицы?
__________________
полезное на axForum, github, vk, coub.
Старый 19.03.2009, 14:27   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Может быть кеш дурит ?
Попробуйте перед выборкой сделать
X++:
inventTable.disableCache(true);
Старый 19.03.2009, 14:42   #5  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
Какие параметры кэширования у вас установлены для этой таблицы?
Found.
Сравнение слоев показывает, что изменены только:
ModifiedDate #Yes
ModifiedTime #Yes
ModifiedBy #Yes
CreatedDate #Yes
CreatedTime #Yes
CreatedBy #Yes

AX3.0 sp5 fp2 (Oracle 10g)

Цитата:
Может быть кеш дурит ?
Попробуйте перед выборкой сделать
не помогает....
Старый 19.03.2009, 15:01   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
Сравнение слоев показывает, что изменены только:
Ну при чем здесь "изменены"?
По-умолчанию у этой таблицы свойство CacheLookup = found.
В хелпе написано.
Цитата:
All successful caching key selects are cached. All caching key selects are returned from cache if the record exists there. A select forupdate in TTS will force reading from the database and replaces the record in the cache.

This is typically used for static tables like ZipCodes where the normal case is that the record exists.
вы сделали insert. запись помещена в кэш. поэтому запрос и возвращает.

не очень понимаю, почему у вас не работает disableCache. в принципе должен. либо вы его не туда поместили. либо он на самом деле не работает в Оракле.
__________________
полезное на axForum, github, vk, coub.
Старый 19.03.2009, 15:08   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Может транзакция на момент перечитывания каким то чудом не откатилась ?

Что говорит appl.ttsLevel() ?
Старый 19.03.2009, 15:10   #8  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
Ну при чем здесь "изменены"?
По-умолчанию у этой таблицы свойство CacheLookup = found.
так я же и ответил:

Цитата:

Цитата:
Какие параметры кэширования у вас установлены для этой таблицы?
Found.
Сравнение слоев показывает, что изменены только:
ModifiedDate #Yes
ModifiedTime #Yes
...
Старый 19.03.2009, 15:17   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
так я же и ответил:
Цитата:
Протормозил. Извините. Подумал, что вы нашли вот такие изменения...
__________________
полезное на axForum, github, vk, coub.
Старый 19.03.2009, 15:25   #10  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
Может транзакция на момент перечитывания каким то чудом не откатилась ?

Что говорит appl.ttsLevel() ?
на throw как и положено = 0. К тому же я пробовал из внешнего джоба запрос делать. Все то же...
Старый 19.03.2009, 15:35   #11  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
В принципе до вставки записи в базу можно не проверять (так как это не работает)
X++:
        inventTable = null;
        inventTable.clear();
        inventTable.initValue();

        if (InventTable::exist(sCode))
             throw error(strfmt("Запись существует", sCode));
А положиться на уникальный индекс по itemId. С другой стороны, если в данной точке, мне нужно проверить другое поле, причем оно должно быть неуникальным, то добавить уникальный индекс я не могу.
Цитата:
A select forupdate in TTS will force reading from the database and replaces the record in the cache.
делать forupdate, когда он мне не нужен, тоже как-то некрасиво...

еще чудеса. InventTable::exist(sCode) может выдать, что сущ. не первая запись, а скажем 14-я

Последний раз редактировалось Eldar9x; 19.03.2009 в 15:53.
Старый 19.03.2009, 15:50   #12  
petr is offline
petr
Участник
Соотечественники
 
561 / 201 (8) ++++++
Регистрация: 30.05.2005
Адрес: Швейцария
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
делать forupdate, когда он мне не нужен, тоже как-то некрасиво...
Не думаю, что это некрасиво. В стандарте достаточно мест, где запись выбирается для обновления, хотя затем никакого обновления не происходит. Насколько я понимаю, именно для того, чтобы получать актуальную версию, в не зависимости от того правильно ли отрабатывает кэш или нет.

Для примера можно посмотреть классы работы с журналами главной книги - ledgerJournalEngine - например.
Старый 19.03.2009, 15:56   #13  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
ура, нашел. flush inventTable; и все путем
Старый 19.03.2009, 16:30   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
ура, нашел. flush inventTable; и все путем
Значит кеш.
Почему же у вас disableCache(true) не помог ?
Такого не должно быть.

Как вы его использовали ?
Старый 19.03.2009, 16:38   #15  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
Как вы его использовали ?
X++:
 inventTable = null;
        inventTable.clear();
        inventTable.initValue();

inventTable.disableCache(true) 
        if (InventTable::exist(sCode))
             throw error(strfmt("Запись существует", sCode));
есть подозрение, что если перенести это в InventTable::exist (что, разумеется делать, не стоит)
или делать запрос по курсору inventTable прямо в методе, то это тоже сработает. Завтра проверю.

Цитата:
Не думаю, что это некрасиво. В стандарте достаточно мест, где запись выбирается для обновления, хотя затем никакого обновления не происходит. Насколько я понимаю, именно для того, чтобы получать актуальную версию, в не зависимости от того правильно ли отрабатывает кэш или нет.

Для примера можно посмотреть классы работы с журналами главной книги - ledgerJournalEngine - например.
не только поэтому. Пример: Проверяются два поля. Соответственно нужно два курсора. Если при проверке окажется, что выбралась одна и та же запись, получим блокировку. Не проверял, но рисковать не хочется.

Последний раз редактировалось Eldar9x; 19.03.2009 в 17:04.
Старый 19.03.2009, 17:05   #16  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Правильное подозрение
Проще в данном случае код из Exist() вытащить.
Старый 19.01.2010, 17:16   #17  
Maximin is offline
Maximin
NavAx
NavAx Club
 
412 / 346 (12) ++++++
Регистрация: 09.10.2002
Адрес: Москва
Наступил на те же грабли, но в AX 4.0 SP2.
Пытаюсь импортировать данные группой определений, одна из таблиц - UnitConvert (с режимом кэширования EntireTable). В результате импорта (есть доработка, которая всю сессию импорта проводит в одной транзакции), и вылетания в середине импорта ошибки по throw(), получаем, что изменения в других, "нормальных" таблицах откатились, а в UnitConvert видны записи, которые вставлялись туда импортом. Ессно, в самой базе таких записей нет, но при попытке импортировать заново - выпадает сообщение о уже существующих записях (срабатывает SysDataImportDefBase.findFromKeyData.
Добавление же в него

X++:
    common = new DictTable(_tableId).makeRecord();
    flush common;
, либо _forUpdate = true ситуации не исправляет, т.к. по-видимому, первое сбрасывает кэш клиента, а не AOS, а второе не смущает режим EntireTable. Зато ситуацию отлично исправляет Menuitem SysFlushData с модификатором Server. Т.е. мешает кэш на AOS.
Сбрасывать весь кэш AOSа при начале импорта или его неуспешном окончании из-за какого-то товарища, неправильно заполнившего импортные таблицы как-то не комильфо.
Есть ли другие способы решения?
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты...

Последний раз редактировалось Maximin; 19.01.2010 в 17:19.
Старый 19.01.2010, 18:18   #18  
Maximin is offline
Maximin
NavAx
NavAx Club
 
412 / 346 (12) ++++++
Регистрация: 09.10.2002
Адрес: Москва
Пока сделал тупо - перед импортом и после него (метод SysDataImportDefBase.importTable) очередной таблицы делает вызов серверного static метода с упомянутыми выше двумя строками, точнее Dictionary::dataFlush(_tableId). Работает.
Но как ни странно - после неудачного импорта (падает на другой таблице, в UntiConvert к тому времени всё уже залито нормально) вставленные в UnitConvert строки все равно видны, т.е. уже после вставки записей кэш все равно не очищается?!
В общем, как бы то ни было, при повторных запусках записи ищутся/не ищутся правильно. Принцип идемпотентности почти соблюден.
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты...

Последний раз редактировалось Maximin; 19.01.2010 в 18:42. Причина: Уточнил замену на Dictionary::dataFlush(
Старый 19.01.2010, 22:15   #19  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Мне кажется что проблема в том что кеш не поддерживает нормально транзакции. Т.е. в нем остались грязные данные транзакции которую откатили.

Хороший повод написать запрос в MBS на исправление.

Думаю что можно просто сбрасывать серверный кеш перед импортом и при перехвате ошибки. Издержки не так велики - это ведь не редактирование записи, а достаточно редкий массовый импорт. Тем более что кеш можно сбросить для конкретной таблицы (если не ошибаюсь - SysFlushData для всех сбросит - это слишком убойный вариант) в нашем случае достаточно выполнить flush common на сервере.
Старый 20.01.2010, 01:38   #20  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Я думаю, что это очень сложно грамотно исправить на уровне МС.
Пришлось бы каким-то образом отслеживать на уровне ядра, какие записи вставлялись в этой транзакции, и удалять из кэша только эти записи - ведь прост очищать кэш тоже не очень кошерно
За это сообщение автора поблагодарили: glibs (1).
Теги
ax3.0, ax4.0, cache, баг, кэширование, ошибка

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Баг стандартного механизма перекрытия лукапа miklenew DAX: Программирование 5 09.04.2009 14:40
Не корректно сохраняет запись в inventTable Starling DAX: Программирование 8 31.03.2008 15:30
reNameItemId для InventTable DreamCreator DAX: Программирование 9 26.12.2006 10:11
Программно записи в InventTable djoker DAX: Программирование 8 02.12.2004 16:59
Не отображается товары в Form\InventTable! Zelenhof DAX: Программирование 6 15.01.2003 17:55

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

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

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