21.10.2014, 16:11 | #1 |
Участник
|
i-neti: Решение проблемы с поиском новой цены в Dynamics AX
Источник: http://i-neti.ru/blog/230
============== Многие сталкиваются с такой проблемой как отсутствие только что измененной цены. К примеру что то там стандартный механизм посчитал, мы изменили 1 параметр и нам нужно найти новую цену, в итоге она не находится. Проблема кроется в кешировании аксаптой класса priceDisc_Price. Аксапта достает этот класс из кэша, видит что там переменная PriceFound = true и не ищет ничего. Решением является изменение класса для работы без использования кэширования. Видимо этот механизм не до конца был проработан разработчиками Microsoft Dynamics. Источник: http://i-neti.ru/blog/230
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
22.10.2014, 06:50 | #2 |
Участник
|
Цитата:
...скорее всего, сам разработчик не разобрался. 1. ПРОИЗВОДИТЕЛЬНОСТЬ ни в коем случае НЕ стоит изменять режим кэширования на продакте. Конечно, попробуйте на тестовой базе. И убедитесь, что отключение кэширования таблицы PriceDiscTable немедленно приводит к DDOS'у SQL сервера мелкими запросами по этой таблице. И это неспроста. Изначальные разработчики Аксапты не боялись мелких, простых и частых запросов к SQL именно потому, что отлично работал кэш. Поэтому зачастую лучше написать пару простых запросов в цикле (они будут брать данные из кэша) вместо сложного SQL-запроса с join. 2. ПРОБЛЕМА ПО СУТИ Сама постановка проблемы является надуманной. Дело в том, что кэш так или иначе обновится максимум через 15 минут. В многопользовательской системе 15 минут обычно не влияют на работу пользователей. Пользователь1 обновил цены, в течение 15 минут у Пользователя2 цены гарантировано будут обновлены. Если в течение этих 15 минут у Пользователя2 будут задействованы старые цены - обычно ничего критичного не происходит. Это нормально. 15 минут становятся проблемой, когда появляется 1 (один) тестер и гоняет бизнес-процессы. Тогда да, наличие кэша и период до 15 минут становятся проблемой. Но это проблема тестирования, а не реальных бизнес-процессов. В тестировании перед каждым новым бизнес-процессом надо тупо сбрасывать кэши командой "Tools \ Caches \ Refresh data". |
|
|
За это сообщение автора поблагодарили: AlexeyS (1), gl00mie (3). |
22.10.2014, 12:41 | #3 |
Участник
|
Цитата:
Решением является изменение методов \Data Dictionary\Tables\LedgerJournalTrans\Methods\checkAllowEdit и \Classes\LedgerJournalEngine\allowEdit. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
22.10.2014, 12:47 | #4 |
Участник
|
Жжёшь, Napalm
|
|
28.10.2014, 02:06 | #5 |
Участник
|
Проблема отсутствия искомой цены не может быть надуманной, ибо для того и нужна система, чтоб получать нужные данные.
Тут ещё нужно понять, о каком кэше идёт речь. Дело в том, что класс PriceDisc_Price для поиска цен использует класс PriceDisc, который найденные значения добавляет в глобальный кэш SysGlobalObjectCache. Так что вряд ли эта проблема связана с кешированием таблицы. Что такое "кеширование класса", я, честно говоря, не знаю. В классе PriceDisc в двух местах есть баги, которые "теряют" найденную цену. Вкратце, они в цикле присваивают ссылку на буферную переменную. X++: // Begin: Alexey Voytsekhovskiy Not to lose the buffer! actualDiscTable = priceDiscTable.data(); //actualDiscTable = priceDiscTable; // End: Alexey Voytsekhovskiy Думаю, есть смысл сообщить куда следует.
__________________
Felix nihil admirari |
|
|
За это сообщение автора поблагодарили: kashperuk (5), gl00mie (2), alex55 (1), S.Kuskov (5), Kabardian (7). |
28.10.2014, 03:53 | #6 |
Участник
|
Цитата:
обратите внимание, что в вашем утверждении ничего не сказано про время Цитата:
которые вместо использования стандартных механизмов выполняют закат солнца вручную. |
|
28.10.2014, 17:06 | #7 |
Участник
|
Цитата:
о времени давно уже сказано до нас, что оно - деньги. я тут писал модуль симуляции розничных цен для крупнейшего поставщика автозапчастей, и уверяю тебя, эти люди порвут кого угодно, если новая цена не будет появляться чуть раньше реального времени. вторая часть комментария эмоциональная, но не конструктивная. глобальный кэш -- вполне себе стандартный механизм, как раз созданный для того, где кеширование таблиц не очень эффективно. впрочем, это, как я понимаю, тема для обширных дискуссий. тем более, что используется он не для всех случаев при поиске цен. например, тот же приснопамятный метод findDisc: X++: // To avoid flooding the cache the most granualated setup isn't cached. // ADAXBasis - Begin cacheMode = !(_itemCode == ADAXTableCategoryGroupAll::Table && _accountCode == ADAXTableGroupOfContractGroupAll::Table); // ADAXBasis - End Для моего конкретного случая, когда нужно загружать сотни тысяч новых цен, я это дело отключил. А вот как бы сделать так, чтоб Ваня заинтересовался косяком, про который я написал, и пофиксили бы это дело в консерватории...
__________________
Felix nihil admirari |
|
29.10.2014, 09:05 | #8 |
Участник
|
Да, но только проблема этого кеширования в том, что кеш сбрасывается только для АОСа, на котором происходило "шевеление", а на других оставшихся АОСах глобальный кеш остается неизменным Приходится в некоторых операциях насильно его вручную обновлять.
__________________
Sergey Nefedov |
|
29.10.2014, 10:37 | #9 |
Участник
|
Понимаю, что про другого Ваню, но все же Если объяснишь, на какой версии и как повторить, то зарегистрирую в MS.
__________________
Ivanhoe as is.. |
|
|
За это сообщение автора поблагодарили: kashperuk (3). |
29.10.2014, 11:33 | #10 |
Участник
|
Цитата:
О, вот и доброволец нашелся. Спасибо! |
|
29.10.2014, 17:13 | #11 |
Участник
|
ничего подобного! почитайте же по ссылке что написано: кэш реально global.
__________________
Felix nihil admirari |
|
29.10.2014, 17:14 | #12 |
Участник
|
AX2012 R2, R3
__________________
Felix nihil admirari |
|
29.10.2014, 17:16 | #13 |
Участник
|
кстати, а откуда дровишки про эти 15 минут?
__________________
Felix nihil admirari |
|
30.10.2014, 11:25 | #14 |
Участник
|
__________________
Ivanhoe as is.. |
|
30.10.2014, 17:22 | #15 |
Участник
|
на рабочем проекте я получил ситуацию, когда флажок "цена найдена" был взведён, а переданный буфер оказался пустым. повторять конкретно на том классе сейчас у меня времени нет, но суть примерно такова:
X++: static void tmxTestCustTable(Args _args) { PriceDiscTable priceTable; PriceDiscTable foundPriceTable; PriceDiscTable foundPriceTableData; int maxCust = 5; int i = 1; while select priceTable { info(strFmt("in loop %1: %2", i, priceTable.RecId)); if(i == 2) { foundPriceTable = priceTable; foundPriceTableData = priceTable.data(); info("<-- let's say this is what we were looking for..."); } if(i>maxCust) { break; } else { i++; } } info("---------------------------------------"); info(strFmt("priceTable buffer after %1", priceTable.RecId)); info(strFmt("found reference after %1", foundPriceTable.RecId)); info(strFmt("found buffer after %1", foundPriceTableData.RecId)); } X++: Message (10:19:22 am)
in loop 1: 5637351352
in loop 2: 5637349038
<-- let's say this is what we were looking for...
in loop 3: 5637349039
in loop 4: 5637344655
in loop 5: 5637339598
in loop 6: 5637331591
---------------------------------------
priceTable buffer after 5637331591
found reference after 5637331591
found buffer after 5637349038
__________________
Felix nihil admirari |
|
17.11.2014, 13:40 | #16 |
Талантливый разгвоздяй
|
В эту же тему. Не может ли ошибка со следующим текстом быть причиной, указанного выше бага (навскидку если кто знает ответ)?
Цитата:
Внутренняя ошибка в операции удаления в кэше объектов PriceDisc:FindPrice
Последний раз редактировалось Kabardian; 17.11.2014 в 13:43. |
|
|
|