Показать сообщение отдельно
Старый 07.11.2012, 16:23   #1  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,894 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Проблемы с кэшированием inventSum в DAX2012
Коллега показал интересную граблю. Я пока не уверен на 100% что это системная бага, но очень похоже что это так, так что я решил поделиться. Итак: DAX2012 CU3 (без feature pack). Коллега написал маленький дисплейный метод, который тупо выводит для строки заказа незарезервированный остаток. (Не самый лучший способ с точки зрения производительности, но клиент хочет, да и по большому счету проблема не в этом). Демонстрировал мне несколько раз такую картину: По строке заказа ноль. Он запускает развертывание, система создает плановую закупку, он его утверждает и разносит накладную. Возвращается в заказ и рефрешит строку - там по прежнему ноль. Далее коллега идет и синхронизирует inventSum. Заказ показывает правильный остаток. Дальше по заказу разносится отоброчная накладная. Опять - в строке заказа показывает доступное количество (ненулевое). Если опять отсинхронизировать inventSum, количество меняется на правильное - нулевое.
К своему глубокому изумлению, обнаружил что в inventSum стоит кэширование в режиме notInTTS. Причем стоит давно - по крайней мере с версии 2009. Моя гипотеза, почему вся эта ситуация происходит:
1. Как известно, в большинстве случаев, inventSum обновляется через directSQL. (Исключение - ситуации когда транзакция должна обновить всего одну строку в inventSum).
2. Система кэширования AOS не отслеживает обновлений через directSQL, и продолжает хранить в кэше старые данные. Соответственно - чтения данных через inventOnHand или большая часть прямых запросов через inventSum обрабатываются из кэша и возвращают старые данные.
3. В старых версиях аксапты, эта грабля не порождала такого множества проблем, поскольку в старых версиях из кэша обрабатывались только простейшие запросы с запросом из одной таблицы с всеми полями уникального индекса с выражении where. Поскольку 99% процентов запросов по inventSum идут с джойном по inventDim, механизм кэширования не срабатывал, и данные вытаскивались каждый раз из сиквела. В 2012ой поддержали кэширование для джойнов (возможно не для всех случаев, но для части - точно поддержали) и грабля сработала.

В общем - мы до уточнения тупо отключили кэширование inventSum. Похоже что шансы неправильной работы inventOnHand за пределами транзакции - достаточно высоки, а дополнительная нагрузка от показа количеств на складе во всяких отчетах и дисплейных формах - незапредельная.
Кроме того - я вообще не вижу большого смысла включать какое-либо кэширование у такой волатильной таблицы как inventSum. Я еще могу понять режим NotInTTS для заказов и закупок (обычно их только один человек правит и вероятность конфликта невысока), но понять кто и зачем включил этот режим для inventSum (даже если забыть грабли с directSQL) - я не могу...
За это сообщение автора поблагодарили: macklakov (5), Владимир Максимов (5), Pustik (5), sukhanchik (7), Logger (5), Greggy (1), lev (5), MikeR (5), gl00mie (3), Stitch_MS (2), shogel (1), S.Kuskov (5).