07.08.2009, 15:57 | #1 |
MCTS
|
Опять Кэш
В validateWrite на форме InventTable:
X++: if (!InventTable.RecId && InventTable::exist(inventTable.ItemId)) return checkFailed(strfmt("@SYS58214", inventTable.ItemId)); правильно ли будет, если я заменю этот участок кода следущим? (то есть данные тянутся с сервера, а не клиента) X++: if (!InventTable.RecId && InventTable::tmn_exist(inventTable.ItemId)) return checkFailed(strfmt("@SYS58214", inventTable.ItemId)); tmn_exist(): static server boolean tmn_exist(ItemId itemId) { InventTable inventTable; ; flush inventTable; select inventTable index hint ItemIdx where inventTable.itemId == itemId; return itemId && inventTable.recId; } |
|
07.08.2009, 16:22 | #2 |
Участник
|
X++: if (!InventTable.RecId && InventTable::exist(inventTable.ItemId)) X++: if (InventTable::exist(inventTable.ItemId))
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy |
|
07.08.2009, 19:04 | #3 |
Участник
|
А отменить кеширование таблицы InventTable нельзя? CacheLookup = None
|
|
08.08.2009, 16:24 | #4 |
MCTS
|
ivas, не совсем понимаю, как это мне должно помочь....
Владимир Максимов, этим действием я не получу себе еще больше проблем? |
|
08.08.2009, 17:04 | #5 |
Member
|
Отменить кэширование можно, но может пострадать производительность. Обычно код пишется таким образом, что он рассчитывает на работающий механизм кэширования.
Я в таких подлых случаях пишу inventTable.disableCache(true); Впрочем, как лучше — не знаю. Eldar9x, а какая у вас проблема, если не секрет? А то я сталкиваюсь с проблемой, когда в InventTableModule регулярно появляются записи, которых нет в InventTable. Пока не словил причину. Но тоже склонен грешить на кэш.
__________________
С уважением, glibs® |
|
|
За это сообщение автора поблагодарили: Logger (2). |
08.08.2009, 20:04 | #6 |
MCTS
|
Цитата:
А то я сталкиваюсь с проблемой, когда в InventTableModule регулярно появляются записи, которых нет в InventTable.
Вообще проблемы начались, когда разрешили удалять записи в таблице номенклатур. И вообще, я не понимаю, для чего это проверка там вставлена? В inventTable есть уникальный индекс по ItemId, зачем еще этот код? Последний раз редактировалось Eldar9x; 08.08.2009 в 20:06. |
|
|
За это сообщение автора поблагодарили: glibs (2). |
10.08.2009, 16:53 | #7 |
MCITP
|
Цитата:
Сообщение от Eldar9x
и это тоже, кстати. И еще в других связанных таблицах. Чистил руками в итоге. Точно пока сказать не могу, как это происходит. Вроде как, при сохранении записи, если одно из обязательных полей связанной таблицы не заполнено.
Вообще проблемы начались, когда разрешили удалять записи в таблице номенклатур. И вообще, я не понимаю, для чего это проверка там вставлена? В inventTable есть уникальный индекс по ItemId, зачем еще этот код? Думаю можно этот код убрать. Либо как вариант заменить X++: if (InventTable::exist(inventTable.ItemId)) X++: ttsBegin; if (InventTable::find(inventTable.ItemId, true)) {...} ttsCommit;
__________________
Zhirenkov Vitaly |
|
10.08.2009, 18:32 | #8 |
Участник
|
Как указал glibs кеширование влияет на производительность. Но здесь нет однозначного ответа.
По умолчанию, у InventTable режим кеширования Found. Т.е. кешируются только те записи, к которым было обращение (поиск). Следовательно, этот режим кеширования имеет смысл оставить, если каждый пользователь работает в основном с небольшим набором номенклатуры. Или сам справочник номенклатуры небольшой. Если же большинство пользователей работает со всей картотекой номенклатуры, то нет никакого смысла в кешировании. У нас кеширование InventTable отключено. Справочник порядка 50 тысяч позиций. Проблем нет. Хотя, удаление записей запрещено Цитата:
Сообщение от Eldar9x
И вообще, я не понимаю, для чего это проверка там вставлена? В inventTable есть уникальный индекс по ItemId, зачем еще этот код?
Если оставить только индекс, то, во-первых, нет возможности "рулить" текстом сообщения об ошибке, а, во-вторых, будет выполнена куча лишних проверок до попытки сброса изменений в таблицу. Думаю, добавятся еще проблемы со связанными таблицами, но здесь не уверен. Собственно, можно попробовать вообще убрать эту проверку и посмотреть к чему это приведет в случае попытки создания дубля. |
|
|
За это сообщение автора поблагодарили: Eldar9x (2). |
10.08.2009, 20:00 | #9 |
Member
|
Цитата:
Сообщение от Владимир Максимов
...
кеширование влияет на производительность. Но здесь нет однозначного ответа ... Если же большинство пользователей работает со всей картотекой номенклатуры, то нет никакого смысла в кешировании. ... InventTable::find(...) А точнее, когда запись выбирается по первичному ключу. Если код работает на сервере приложений, то в таком случае будет лишнее обращение на сервер БД. Номенклатура там скорее всего будет тоже в кеше, поэтому потери производительности вы можете не ощутить визуально. Впрочем, если запускается долгоиграющая периодическая процедура (типа закрытия склада), в которой может очень-очень много раз вызываться InventTable::find(...) подразумевая, что кеширование включено, производительность может просесть заметно. Не говоря уже о лишнем трафике (Аксапта имеет привычку выбирать все поля в записи). Если же код будет выполняться на клиенте (display методы, если по-хорошему), то потеря производительности при отключении кеширования будет заметна даже невооруженным глазом. Когда я был помоложе, то тоже увлекался отключением кеширования. Но все-таки пришел к тому, что не стоит. Вот вам джоб. X++: static void glibs(Args _args) { InventTable inventTable; Counter i; TimeOfDay startTime, endTime; ; startTime = timenow(); for (i = 1; i <= 10000; i++) { inventTable = InventTable::find("Test"); } endTime = timenow(); info (strfmt("%1", endTime - startTime)); } У меня разница приблизительно на порядок получилась.
__________________
С уважением, glibs® |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
11.08.2009, 07:42 | #10 |
MCTS
|
Цитата:
Вопрос момента проверки на уникальность.
Если оставить только индекс, то, во-первых, нет возможности "рулить" текстом сообщения об ошибке, а, во-вторых, будет выполнена куча лишних проверок до попытки сброса изменений в таблицу. Думаю, добавятся еще проблемы со связанными таблицами, но здесь не уверен. Собственно, можно попробовать вообще убрать эту проверку и посмотреть к чему это приведет в случае попытки создания дубля. Цитата:
Хотя, удаление записей запрещено
Цитата:
У меня разница приблизительно на порядок получилась
|
|
11.08.2009, 14:04 | #11 |
Участник
|
Цитата:
Ну, а далее выполняешь все необхоимые проверки и программно меняешь значение поля на указанное, если это возможно. Или сообщение, почему уже поздно... |
|
11.08.2009, 14:20 | #12 |
Участник
|
glibs
Я же говорю, нет однозначного ответа. Зависит от конкретной ситуации и надо смотреть "по месту" что выгоднее: возможная потеря производительности или актуальность данных. Для нас критичным оказалась именно актуальность данных. Почему? Это уже отдельный вопрос. По сути, единственное место, где реально ощутима потеря производительности - это display-методы. Коды циклических процедур все-таки не настолько "тупые", чтобы многократно делать поиск внутри цикла. А если настолько, то на этот случай и нужны программисты, чтобы это исправить Можно ведь сделать и "закат солнца вручную". В смысле, скидывать найденные записи во временную таблицу внутри цикла. Своеобразный локальный кеш получится. Насчет закрытия склада - не понял. Где там многократное обращение к одной и той же записи InventTable? Там же единственный цикл именно по InventTable, а потом выбранная запись передается как параметр. Нет повторного InventTable::find() |
|