Эксперименты с FLUSH в VFP9 | |
---|---|
Sergey Fadeev Сообщений: 106 Откуда: Чебоксары Дата регистрации: 07.02.2005 |
Возникли тут некоторые ошибки с VFP9. Проект, который без проблем работал на VFP8SP1, вдруг стал неправильно читать после редактирования одиночную запись (она там всего одна) в свободной таблице. Новых возможностей не использовал (SET ENGINEBEHAVIOR 70). Сессия на том участке кода одна (глобальная), но таблица открывается дважды (в разных областях и процедурах) под разными алиасами. Так вот во 2-ой процедуре под другим алиасом читается старое содержимое записи, которая до этого уже была изменена в 1-ой процедуре. Ошибка довольно странная - если перед вызовом 2-ой процедуры (где будет повторно открыта таблица) в вызывающей процедуре поставить команды SELE <алиас таблицы> и BROWSE, то 2-ая процедура прочитает новое содержимое записи, если не ставить - прочитает старое. Видимо, передергивание указателя записи вызывает запись в какой-то другой, более низколежащий буфер, который потом успешно читается 2-ой процедурой. Повторяю, раньше (в VFP8SP1) этой проблемы не существовало. Попытка повторить ошибку в маленьком тесте не привела к успеху. Попытка сделать усеченный (рафинированный) тестовый пример из реального проекта также не привела к успеху - ошибка исчезла. Поэтому показать здесь ничего не могу...
Проблема решена постановкой любой из команд FLUSH FORCE или =SYS(1104) в начале 2-ой процедуры - ДО команд работы с таблицей. Но это так - вступление. Может кого-то заинтересует. Может кто-то тоже на такое же наткнется и будет знать, как действовать... А написать я хотел вот что. Данная ошибка сподвигла меня на то, чтобы поэкспериментировать с командой FLUSH. Тем более, что в VFP9 эта команда расширена. Написал я программку, которая в цикле создает друг за другом одинаковые свободные таблицы по 100 тыс. записей с мемо-полями и не закрывает их. Сначала создаст и заполнит 1-ую таблицу, после чего переходит к созданию и заполнению 2-ой и т.д. Я сижу в FAR'е и наблюдаю за созданием и ростом этих таблиц (Ctrl+R - обновление содержимого панели с файлами). И вот какие любопытные наблюдения получились (Windows 2000 SP4, ОЗУ 512 Мбайт): 1. Между созданиями и заполнениями таблиц нет никаких команд. Порядок сброса буферов произвольный. Вполне возможна ситуация, когда создается уже 4-ая таблица (она появилась в каталоге), а 1-ая еще не заполнилась (определяю по размеру файла на диске) - т.е. сброс ее буферов еще не завершился. Причем в какие-то моменты времени 2-ая таблица может по размеру быть больше, чем 1-ая (сброс ее буферов идет с опережением предыдущей таблицы). Мемо-поля всегда сбрасываются в первую очередь! Стандартная ситуация - размер .fpt уже полный, а размер .dbf не достигает даже 20% от итогового. 2. После заполнения очередной таблицы перед переходом к созданию следующей стоит команда FLUSH. Такого растягивания на 4 таблицы, как в предыдущем случае, уже нет. Максимум, что возможно - у предыдущей таблицы осталось заполнить небольшой хвостик, а следующая таблица уже создана. Да и то это наблюдается не всегда. Мемо-поля всегда заполняются строго в первую очередь. 3. После заполнения очередной таблицы перед переходом к созданию следующей стоит команда FLUSH FORCE. Таблицы появлялись и заполнялись строго по очередности. Никогда не было такого, что появлялась следующая таблица, а предыдущая еще не до конца заполнена. Но заполнение мемо-полей идет раньше основной таблицы. Отсюда выводы: FLUSH без FORCE действительно не всегда реально сбрасывает буфера на диск. Если действительно требуется сброс на диск, то следует использовать FLUSH FORCE. FLUSH без FORCE скорее всего действительно работает только на уровне самого VFP, а ОС может это дело и проигнорировать. Следует учесть, что мемо-поля в промежутках между FLUSH [FORCE] из-за особенностей внутреннего алгоритма VFP всегда заполняются быстрее. Поэтому в случае внезапного сбоя вполне возможна ситуация, когда файл .fpt содержит больше информации, чем файл .dbf. Не вижу в этом ничего особенно страшного, т.к. все равно в файле .dbf хранятся всего лишь указатели на .fpt. Т.е. "бесхозное" содержимое .fpt не будет видно из программ. Единственное, что может досаждать - впустую занятое место в файле. Но .fpt файлы этим грешат и по другим причинам, поэтому тем, кому не нужна излишняя "припухлость" .fpt файлов, все равно надо периодически их "утрамбовывать". Естественно, что сказанному выше следует верить с оговоркой на возможные погрешности из-за неизвестного мне алгоритма приращения размера .fpt файлов... |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Sergey!
Цитата:Если всё-же сможешь сделать пример демонстрирующий ошибку - не поленись и выложи. Такое 100% возникает при работе РАЗНЫХ процессов - т.е. фокс с одной стороны действительно не сбрасывает "вновь записанное" на диск, а с другой - не читает данные с диска (чего снова то читать, если я буквально секунду назад их считывал) - обсуждалось это и примеры были в FIDO - поищи через Google - причём ИМЕННО в VFP9 был исправлен один баг - при повторном открытии (USE AGAIN или просто USE в другой DS) таймер "запрета на считывание с диска" не обнулялся, а выставлялся в максимум (2-й параметр SET REFRESH) - т.е. в течении тех самых 5-ти секунд (это по умолчанию) нельзя было получить с диска "свежие" данные - независимо от того когда РЕАЛЬНО они последний раз считывались - именно SYS(1104) и помогал - вкупе конечно с "инициацией считывания" - например GO RECNO() или Refresh на "связанный" грид. Чтобы такое происходило в рамках ОДНОЙ программы - для меня новость. Тем паче что физически то файл открывается лишь один раз, и его кэш-структуры как я понимаю тоже едины на все USE AGAIN копии-курсоры... (про фоксовую буферизацию не говорим - буфера там конечно разные)... Вообще поток IO операций можно посмотреть в fileMon - правда не для таких больших объёмов - а то погрязнешь в логе А насчёт fpt - там очень простая структура - BlockSize рулит размером минимального блока... Гораздо опаснее наличие в dbf ссылки на "несуществующий" блок (за пределами fpt файла) чем наличие "левого" блока - это ты правильно подметил... ------------------ WBR, Igor |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Naomi Сообщений: 1796 Дата регистрации: 09.10.2003 |
Еще один момент на тему FLUSH FORCE. Если открыто много таблиц, надо обязательно указывать алиас таблицы, для которой надо выполнить FLUSН. В противном случае, система будет зависать (надо же, не могу подобрать хороший аналог performance degradation). Мы хотели перейти на VFP9 месяца 3 назад. Но я в save методе добавила FLUSH FORCE (потом сообразила, что сделала я это напрасно, т.к. используется транзакция). Так вот, торможение было ужасным. Мой коллега выявил, что происходило это из-за FLUSH FORCE (что интересно, кстати, VFP8 compiler это просто игнорировал). К сожалению, эта моя ошибка дорогого стоила - мы отказались от VFP9 на 3+ месяца. Переходим на 9 со след. недели...
|
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Владимир11111 |
Уважаемые знатоки FoxPro!
Очень интересна проблема , поднятая Сергеем. Если не в тягость, обсудите для посетителей форума. Очень полезно всем. С уважением, Владимир. |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
PaulWist Автор Сообщений: 14618 Дата регистрации: 01.04.2004 |
Надя.
Какие еще подводные камни нащупали в 9-ке? ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
PaulWist Автор Сообщений: 14618 Дата регистрации: 01.04.2004 |
До кучи к FLUSH FORCE, эта команда не является панацеей, к сожалению фоксовский обработчик ошибок не принимает статуса её завершения и отловить событие отработала команда или нет - не представляется возможным, обсуждение эксперимента было здесь forum.foxclub.ru
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Naomi Сообщений: 1796 Дата регистрации: 09.10.2003 |
Еще проблема с listbox in container. Не получается мышью выделить. Мы эту проблему обнаружили в MereMortals Biz Obj Builder. На UT не так давно обсуждалось...
Еще проблема с BuilderX & BuilderB... И известный баг в RI builder (typo). Вроде бы все, но мы еще не начали использовать VFP9 в полной мере по моей вине. К счастью, должны перейти со след. недели. |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
piva Сообщений: 18655 Откуда: Курган Дата регистрации: 24.03.2004 |
Не пока SP1 не выйдет - ничего переводить под 9-ку - не буду
------------------ Часто бывает так, что есть над чем задуматься, а нечем. |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Sergey Fadeev Сообщений: 106 Откуда: Чебоксары Дата регистрации: 07.02.2005 |
Ох и муторное же дело из большого проекта пытаться выкусить рафинированный образец. Там ведь десятки других переменных, объектов, открытых таблиц - черт знает, где они могут перекрестно влиять друг на друга и на менеджеры памяти и буферов таблиц. Но попробую сделать еще одну попытку... Русский программистский аналог - "система будет [сильно] тормозить". "Тормозить" - работать, но медленно. Но ведь все-таки работать! . "Зависнуть" - это уже хуже, т.к. управление компьютером окончательно потеряно - поможет только перезагрузка. |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Равиль Сообщений: 6549 Откуда: Уфа Дата регистрации: 01.08.2003 |
Интересные наблюдения. Еще одна возможная причина такого поведения - особенности фокса при работе с таблицами в гриде.
Может не в тему, но как-то участвовал в обсуждении одной странной ошибки (109) возникающей при редактировании таблицы в гриде. Сейчас порылся в поиске и увидел, что она снова поднималась matod forum.foxclub.ru - действительно обескураживающее сообщение, особенно для случая эксклюзивно открытой таблицы. Интуитивное решение проблемы нашлось - явный благополучный сброс буфера перед переходом на другую запись, но причина осталась непонятной. Поработал в 9-ке и кое-что прояснилось благодаря ошибке (2072), гласящей о том, что нельзя дескать переходить на другую запись, пока не сброшены изменения в текущей. Вопрос - а почему нельзя то? Думаю, что возможная причина в том, что грид является контейнером контролов для которых можно прописать Valid, но эти контролы связаны с полями таблицы. С другой стороны, ничто не мешает изменить эти значения из-вне грида (например командами replace), а как обеспечить согласованность этих изменений и соблюсти валидность в гриде? Вот видимо поэтому фокс и устанавливает временный признак блокировки записи неким "another user" на время редактирования в гриде и снимает его при сбросе буфера, в большистве случаев сброс происходит благополучно и незаметно, а при неудаче ловим в ранних версиях (109), а в 9-ке наконец есть комментарий (2072), правда без объяснения, почему необходим сброс буфера при переходе на другую запись в гриде даже при 5-й буферизации. Может кто-то сможет прояснить ситуацию ? ------------------ Тяжело согнать курсором муху с монитора ... |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Nadya_N!
Этого и стоит ожидать - процесс сброса ВСЕХ буферов это недешевая операция... ------------------ WBR, Igor |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Sergey Fadeev Сообщений: 106 Откуда: Чебоксары Дата регистрации: 07.02.2005 |
Цитата:Удалось сделать такой пример. И немножко поиграть с условиями возникновения ошибки. Просьба к знатокам VFP - посмотрите, пожалуйста, чего я там понаписал. А то я на VFP не так давно и поэтому не так уверенно себя чувствую, как в FPD. Может я чего-то там "не включил", может какие-то установки по умолчанию приводят к такому эффекту. Если я виноват - посоветуйте, что "включить". Если это действительно ошибка VFP9 - может кто-нибудь, кто общается с Алексеем Цингаузом (насколько я понял, этими вещами занимается он), напишет ему. А вот собственно сам пример:
|
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Sergey Fadeev Сообщений: 106 Откуда: Чебоксары Дата регистрации: 07.02.2005 |
Забыл добавить. В принципе роль "левого" буфера может выполнять более низкоуровневый буфер (упомянутый в моем первом сообщении), который не успел обновиться...
|
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Sergey!
Это явно НЕ относится к первоначальной ситуации - тут ты сам, вполне намеренно поставил фокс в заведомо ошибочную ситуацию. У тебя есть контрол привязанный к полю - в него введено ОДНО значение (причём отличное от изначального и оно НЕ сброшено в таблицу - вообще для невидимого и неактивного текстбокса это весьма проблематично сделать). Потом "напрямую" ты вводишь ДРУГОЕ значение в это-же поле, но поскольку ты не сделал txt.Refresh или по иному не обновил привязанный контрол, ты и имеешь описанный конфликт. Я не знаю почему FLUSH действует на буфер контрола - возможно это так и задумано... Также очень странно, но добавление к запросу опции WITH (BUFFERING=.T.) тоже решает проблему, хотя я и не думал что это должно работать с неявными буферами контролов... А вот про какие ещё неявные буферы идёт речь (те что существуют БЕЗ наличия привязанных контролов с модифицированным Value) я пока так и не понял... P.S. Ну очень запутанный и нетривиальный код (в плане его работы, а не синтаксиса конечно) - неужели реально где-то необходима такая сложная и нестандартная совокупность/последовательность действий? P.P.S. set enginebehavior 70 лучше убрать (пуская и не сразу, а постепенно исправляя те ошибки, про которые фокс раньше не беспокоился) - это "аварийная" установка... С "новыми возможностями" она не имеет ничего общего - это лишь исправление старых ошибок. P.P.P.S. Да. ещё - приведенный код работает одинаково и на VFP7SP1 (без SET конечно) и на VFP8SP1 - поскольку тут ошибка именно в логической последовательности действий с контролами а не с чем-то ещё... ------------------ WBR, Igor |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
MichaelD Сообщений: 7578 Дата регистрации: 14.05.2005 |
Hi, Igor & All!
Только чтобы отделить один вопрос от другого: "сохранение изменений" != "получение последних изменений"... 1) О "получение последних изменений": Цитата:Да именно в этом контексте и обсуждалось... на стороне клиента, стремящегося "на автомате" получить "свежие данные" Цитата:ну т.е. второй параметр у SET REFRESH "рулит авто-обновлениями" данных... а "принудительное" обновление можно осуществить явно: Цитата:SYS(1104) + GO RECNO() + AnyObject.Refresh() -> приводили к явному получению+отображению свежих данных... 2) О "сохранение изменений": после любой попытки "удачно завершённой транзакции" (TableUpdate()=.T.) следует попросить систему "освободить буфера" -> FLUSH [FORCE or Calls the Windows API FlushFileBuffers], ... это следует видимо ДЕЛАТЬ ВСЕГДА (если у вас сохранение не на VFP-COM+ сервере, где МОЖЕТ БЫТЬ? могут быть послабления ;) ) Отредактировано (26.08.05 11:04) ------------------ С уважением, Михаил Дроздов, Пермь, Россия |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Sergey Fadeev Сообщений: 106 Откуда: Чебоксары Дата регистрации: 07.02.2005 |
Цитата:Согласен - приведенный пример ОЧЕНЬ СИЛЬНО отличается от реального кода. Я специально все ОЧЕНЬ СИЛЬНО упростил, т.к. тянуть кучу процедур, полей и файлов смысла не было. Цитата:В реальном коде этот textbox видимый, активный, далеко не последний в списке редактируемых полей и в него ручками вбивали информацию, которая, тем не менее, не видна в выборке. В реальном коде не видны и изменения в полях, НЕ ПРИВЯЗАННЫХ к каким-либо контролам, сделанные только через REPLACE. Просто я здесь для упрощения не стал вводить 2 поля - думал, что и так будет понятно. Специально для этого случая переделал тестовый пример. Цитата:Во-первых, см. переделанный тестовый пример. Та же ситуация с полем, несвязанным с каким-либо контролом. У меня в реальном проекте все так и происходило. Так что txt.Refresh здесь непричем. Во-вторых, я понимаю, если бы игнорировалось значение, присвоенное только через .Value='' (или введенное ручками в видимом контроле). Но как объяснить, что игнорируется и команда REPLACE для поля, которое на форме НИКАК НЕ ПРЕДСТАВЛЕНО? Причем новое значение, введенное через REPLACE, видно при обращении к этому полю и невидимо для SQL-выборки! Очень жаль, что ты увидел только эффект контрола и не заметил REPLACE, делающий то же самое и точно так же игнорируемый. Присвоение контролу в примере нужно только для появления эффекта ошибки (об этом я писал), а НЕ ДЛЯ ТОГО, чтобы сказать - смотрите, .Value='' не обновляет таблицу. Именно на REPLACE я и обращал внимание... Цитата:Для меня это тоже непонятно... Цитата:Так вот что надо включить для подстраховки! Спасибо за подсказку! Прочитал теперь о этой новой фиче в хелпе. Хотя значение по умолчанию для WITH (BUFFERING=lExp) меня несколько обескураживает. Не таким оно должно быть на самом деле. Т.е. в общем случае все те многочисленные изменения, которые успевает сделать какая-либо программа, будут попросту по умолчанию не видны САМОЙ ЖЕ ПРОГРАММЕ в ее SQL-выборках. Я понимаю, когда невидимы изменения, сделанные другими пользователями в сети, до тех пор, пока они не сбросят изменения на сетевой диск. Но чтобы были невидимы СОБСТВЕННЫЕ, причем ПРЯМЫЕ изменения в ТАБЛИЦЕ!... Цитата:Посмотри обновленный пример. Там поле теперь вообще не привязано к контролу, но ситуация все та же... Цитата:Как я уже сказал, все очень сильно переделано специально под пример - чтобы было все рядом, вместе, в одном методе и без показа чего-либо на экране. Конечно же, никто не будет все пихать в Init() и делать формы без видимых объектов. В реальном проекте все распихано по соответствующим методам, событиям, процедурам и логика там другая. Я просто сконцентрировал в одном месте последовательность команд, приводящую к ошибке... Цитата:Убрал из примера. В проекте буду убирать постепенно... Цитата:У меня под рукой VFP8SP1 уже не было - поэтому не проверял. Сейчас сходил, проверил на чужой машине - действительно, и в VFP8SP1 такая же ситуация! А в реальном проекте VFP8SP1 работал корректно! Значит, что-то я слишком уж сильно упростил - наверное, выкинул какие-нибудь несущественные на первый взгляд команды, которые "гасили" ошибку в VFP8SP1. Там действительно очень тяжело изначально догадаться, какая же команда уберет ошибку... Вот измененный пример:
|
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Sergey!
Да, запутал ты дело слегка ;) Ну зато тема интересная. Наличие "активного" текстбокса действительно тут ключевой момент. Цитата:Поскольку дело не в "поле", а в "записи". Цитата:Нет, не понятно. Теперь значительно лучше Хотя для ПОЛНОТЫ понимания нужно было-бы и саму форму сделать видимой - т.к. без этого никак не "обновить" текстбокс... Цитата:Да, поскольку не сохранилась ВСЯ запись. Это можно наблюдать, если запустить параллельно второй экземпляр фокса, и организовать в нём принудительное чтение данной таблицы (например SET REFRESH 1, 1), а сам тестовый пример запустить пошагово. Цитата:Оно не игнорируется, просто не происходит ЗАПИСИ данных на диск (точнее в кэш ОС но тут это без разницы), об этом ниже. Цитата:Да, прямые обращения запрашивают данные из фоксового КЭША - т.е. даже то что на диск ещё не сохранено, то будет видно таким (xBase) командам. Цитата:Да верно! Потому что на самом деле SQL запрос читает данные с ДИСКА (опять же точнее говоря - из кэша ОС), даже имеющийся внутренний фоксовый кэш (даже не буфер при включенной буферизации!) игнорируется. Я заметил REPLACE, но не мог понять почему и он ведёт себя неадекватно, теперь же увидел Цитата:ИМЕННО! При таком присвоении возникает БЛОКИРОВКА!Добавь в отладчике в watch окно ISRLOCKED() и проследи за его поведением! Это IMHO ключевой момент. .Value = ... взводит блокировку, и потом НИКТО эту блокировку не снимает! А фокс из-за этого и не производит записи данных на диск, поскольку запись блокирована. Цитата:Дело в том, что REPLACE обновляющий ОДНУ запись работает по примерно следующей схеме: - блокирует запись - вносит изменения - разблокирует При этом фокс обычно производит физическую запись (ну точнее переправляет данные из своих внутренних кэширующих структур ОС - сама ОС тоже может некоторое время держать данные в памяти - но это уже другой вопрос) в момент разблокирования. ОДНАКО если блокировка была наложено ДО выполнения REPLACE, то он не блокирует (т.к. 2 раза заблокировать нельзя) и не разблокирует запись! Соответственно никакой записи и не происходит! Теперь понятна роль FLUSH - он производит разблокирование, и данные из кэша уходят дальше. WITH (BUFFERING=.F.) действующее по умолчанию наверное более корректно определить как "читать данные с диска или из кэша ОС" - т.е. отметить что не только "мимо" буферизации, но и мимо внутреннего фоксового кэша таблицы. Цитата:Нет именно таким - это обеспечивает совместимость со старыми версиями - первостепенное отличие VFP от прочих сред Цитата:Не совсем так... Все те изменения которые остались в буфере (при включенной буферизации - при этом лишь для режимов 4 и 5 это будут "многочисленные изменения"), и те, которые остались в заблокированных записях (обычно это ОДНА запись - если принудительно не блокировать несколько записей). Поскольку авто-блокировки (в т.ч. и та которую мы рассматриваем - т.е. накладываемая при .Value = ...) снимаются например при перемещении на другую запись... Цитата:В том то и дело что они не "прямые", а идут сначала в буфер (если он есть), потом в фоксовый кэш (а SQL запросы идут МИМО этого кэша) и лишь в конце (в частности при снятии блокировки или при FLUSH) уходят далее - в файловый кэш ОС - уже оттуда как я понимаю они будут видны ВСЕМ прогам работающим на данной машине - однако вовсе не факт что они будут записаны на диск, а в случае сетевого файла - отправлены на сервер в его кэширующие структуры... Кстати говоря поможет любая команда или настройка, снимающая блокировку, наложенную "вводом данных в контрол". Я например ВЕЗДЕ перед командами работы с таблицами, перевожу фокус с текущего контрола формы, на специальный "пустой" текстбокс, и конечно проверяю перешёл ли реально фокус, или его "заблокировал" код в Valid или LostFocus - это вызывает срабатывание всех стандартных процедур - в частности и запись содержимого контрола в курсор, и видимо разблокировку записи... Тебе поможет GO RECNO(), UNLOCK, перевод фокуса не другой контрол (конечно форма должна быть для этого видима, и в ДАННОМ примере нужно будет добавить This.Show() + DOEVENTS + This.textbox2.SetFocus()) Также помогает в ДАННОМ ПРИМЕРЕ SET AUTOSAVE ON (не уверен что в реальной программе поможет, особенно после прочтения невнятного описания этой настройки в хелпе ) P.S. Если бы на данный вопрос обратил внимание Aleksey Tsingauz и дал более точное описание процесса, с точки зрения внутренней организации работы фокса с таблицами и с контролами - было бы конечно ещё лучше ------------------ WBR, Igor |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Sergey Fadeev Сообщений: 106 Откуда: Чебоксары Дата регистрации: 07.02.2005 |
Привет, Игорь!
Спасибо за пояснения. Но хотелось бы высказать свои мысли тоже. Цитата:Тут без разницы - делай ее видимой или невидимой - все равно ошибка. Просто мне показалось, что будет нагляднее, если код будет не срабатывать даже без визуальных выкрутасов и без отвлечения на что-либо - вот я и сделал форму невидимой. Цитата:Вот это как раз и плохо. Цитата:На мой взгляд, это неправильно - не должен этим FLUSH заниматься. Если я хочу сбросить буфера, то я должен иметь такую возможность без всяких побочных эффектов типа снятия блокировок. Цитата:Как уже говорил, я пришел в VFP после многих лет работы в FPD. В FPD я, делая REPLACE какого-либо поля, никаким способом уже не мог прочитать старое значение из этого поля. Хоть SQL, хоть не SQL. И считаю это правильным решением. И поэтому значение по умолчанию WITH (BUFFERING=lExp) логичнее было бы сделать таким, как в FPD. Как раз для обеспечения совместимости со старыми версиями. В VFP сделали много наворотов для буферизации. Насколько я догадываюсь, для удобства. Удобно не работать с копиями полей в переменных памяти, а работать напрямую с полями. И только по определенной команде фиксировать эти изменения. Т.е., как я понимаю, создается некая виртуальная среда данных, некий "воздушный замок", в котором значения полей еще нереальны. И будут ли они реальны - зависит от решения программиста. Т.е. форма оперирует со своим контекстом, со своей виртуальной средой. Так вот хотелось бы, чтобы эта концепция была логичной. Если мы работаем в некой виртуальной среде данных, то и ВСЕ команды работы с данными ВНУТРИ ЭТОЙ ФОРМЫ должны работать в контексте этой формы. Цитата:Мда... Что-то мне такие "обходные маневры" не нравятся. По-моему, это уже признак того, что что-то в концепции напутано. Мне кажется, что интерфейс (контролы, их буфера и их Valid(), LostFocus()), блокировку и работу с движком данных не стоило вязать в такой узел, раз приходится ТАК перестраховываться. |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Sergey!
Цитата:Это исторически сложилось - на самом деле в FPD всё было точно так-же. Единственное заметное отличие состоит в том, что FPD перед исполнением SELECT выполняет запись на диск данных из своего кэша - для заблокированных явно и модифицированных записей (для НЕзаблокированных явно записей это и не нужно т.к. для них REPLACE выполняет автоблокировку...) Цитата:1) Должен - это его прямая обязанность. 2) Я неправильно выразился - не FLUSH вызывает снятие блокировки, а наоборот - снятие блокировки с записи вызывает её запись на диск (это не совсем FLUSH т.к. записывается только текущая запись). Явно наложенные блокировки FLUSH не трогает, так что повода для беспокойства нету! Цитата:Ты не прав - единственное видимое отличие - SELECT в FPD вызывает перед своим исполнением неявный FLUSH. А так - как и в VFP SELECT читает данные с диска, а не из кэша. Это легко увидеть если запустить 2 копии FPD и в одной менять данные в таблице, ЗАПИСЫВАЯ их принудительно (тот же FLUSH), а в другой: a) делать "прямое" чтение данных из заранее открытой таблицы. b) делать SQL запрос из этой-же таблицы. Результаты будут РАЗЛИЧНЫЕ. Цитата:Рассматриваемая проблема не имеет отношения к буферизации - это проблема (или особенность) работы системы кэширования считанных с диска данных. Про буферизацию ты в общем правильно понимаешь Цитата:Сложно сказать - поведение SELECT SQL было таковым ещё в FPD (происходило чтение с диска, даже мимо файлового кэша фокса) - сделать "по умолчанию" отличающееся поведение в VFP - значит нарушить принцип обратной совместимости. Поэтому и было оставлено старое поведение. ХОТЯ я считаю что опцию WITH (BUFFERING=...) и соответствующую настройку SET SQLBUFFERING (которая конечно по умолчанию ДОЛЖНА быть установлена в OFF) можно было ввести гораздо раньше, и не тянуть 10 лет Ну да видимо не очень сильно было это востребовано сообществом... Цитата:Это не обходные манёвры - насколько я понимаю так работают все среды - пока что-то "набивается" в поле - ни о каком сохранении данных речи не идёт - и лишь при выходе из поля, или нажатии каких-то специальных клавиш происходит "сброс" данных из буфера контрола куда-то дальше... В фоксе это "осложнено" ещё и явной привязкой контрола к произвольному источнику данных. Если для переменной памяти особых проблем привязка не вызывает (хотя ТОЖЕ порой работа контрола выглядит "странно"), то для поля таблицы - совсем другое дело - поскольку запись в таблицу ДОЛЖНА быть обрамлена блокировкой, то без этого никак нельзя... Ну если конечно не отказываться от привязки контролов - т.е. от задания ControlSource ------------------ WBR, Igor |
Re: Эксперименты с FLUSH в VFP9 | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
Цитата:В FPD не было такого понятия как "буфер таблиц" (точнее, были, но не явные и практически неуправляемые пользователем). Т.е. говорить о какой-то совместимости в этом плане не имеет смысла. Не с чем "совмещать". Если же в VFP не использовать буфер таблиц, т.е. работать "как в FPD", то совместимость налицо. Все работает также как и в FPD. Между FPD 2.6 и VFP9 (где появилось WITH (BUFFERING=lExp) ) было 4,5 версий Visual FoxPro. ВСЕ они в команде Select-SQL не умели работать с буфером. С точки зрения пользователей старых версий VFP - все логично. Совместимость обеспечена. Не надо забывать, что Microsoft отказался от поддержки FPD уже лет 10 тому. Для него "старая" версия - это в лучшем случае VFP6. Цитата:Нет. Тут как раз все логично. Причем именно такая логика была еще в FPD при редактировании в BROWSE-окне. Пока не вышел из поля, изменения этого поля не попали в таблицу. Применительно к VFP. Есть на форме TextBox. Ты начинаешь модифицировать его данные. В какой момент, то, что ты внес должно быть сброшено в поле таблицы? После каждого символа? Не думаю. Логично завершить ввод поля целиком и только потом сбросить то, что ввели. А вот теперь и начинается то, что ты называешь "сложностями". Как определить тот момент, когда ввод данных в TextBox завершен? Т.е. можно начинать все те операции по сбросу буфера. А как увязать завершение ввода в одно поле и завершение ввода всей записи? Чтобы описать все "подводные камни" и возможные "рабочие ситуации", которые могут возникнуть при определении момента завершения ввода в поле и запись надо написать огромную "простыню". Разработчики FoxPro проделали огромную работу по их обработке. Но всего учесть не смогли. Даже не потому, что не заметили, а потому, что не всегда ситуация однозначна. Т.е. не всегда можно однозначно сказать, что вот он момент завершения ввода. Поэтому "правило хорошего тона" - это дать FoxPro понять, что процесс ввода был завершен. Таким индикатором и является явный переход на другой объект ввода. |
© 2000-2024 Fox Club  |