|  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() | 
|  |