![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обновлении данных в многопользовательских программах [D7, IB6.x]
Vovovanych © (2004-05-11 08:58:00)Уважаемы Мастера! Вопрос об обновлении данных при многопользовательском использовании базы данных Interbase: имеется таблица, с которой очень активно работает десяток пользователей (добавляют, редактируют и удаляют записи). Как сделать (без повторного переоткрытия таблицы) чтобы у каждого пользователя была постоянно самая свежая и актуальная информация? Как считывать из базы именно добавленные или обновленные данные?
VoVovanych (2004-05-13 07:14:00) [1]Спасибо всем кто ответил. Вариантов предложена куча, есть над чем подумать. Еще раз спасибо.
SteelAxe (2004-05-12 04:04:00) [2]2VoVovanych © (11.05.04 21:58) [23]CachedUpdates = true
1.Получаешь с сервака набор, открываешь(запуск программы).
2.редактируешь датасет в соответствии с AppEvents.
3.Если ТЕКУЩИЙ клиент редактирует запись, то ВЫВОДИШЬ ЗАПИСЬ В ОТДЕЛЬНОЕ ОКОШКО и пусть он там её себе редактирует. При сохранении этой записи отсылаешь ОТДЕЛЬНЫЙ запрос-сохранение на сервер И В СВОЙ ОТКРЫТЫЙ ДАТАСЕТ со значениями, считанными с ЭТОГО ОКОШКА.
4.В конце работы закрываешь датасет без сохранения сделанных изменений.
Здесь кратко, но, думаю, понятно. Надеюсь подойдёт.
Курдль (2004-05-11 23:44:00) [3]
> проблема в том что нефиг качать данные туда-сюда когда их
> никто не ждет
Если он так упорно настаивает на том, что надо, значит кто-то ждет. Другое дело, что вряд ли следует привязываться к стандартным принципам работы с БД. Например, через сокеты транслировать все обновления "бегущей строкой" от сервака к клиентам (как сделки на бирже) а там уж каждый клиент по наборам данных раскладывает...
Polevi (2004-05-11 23:39:00) [4]да с app-server тоже не фонтан
проблема в том что нефиг качать данные туда-сюда когда их никто не ждет
Курдль (2004-05-11 23:34:00) [5]Да просто может не следует комплексоваться на избранной структуре? Ведь решений может быть немеряно! Уже 100 раз говорили об application server. Да взять какой-нить апач на сервер, забульбенить логику на сервлетах Java, а юзерам - апплеты через браузер (заодно проблема вэб-доступа сразу решится, а то ее в ТЗ всегда как "перспективную фитчу" прописывают :)
Polevi (2004-05-11 23:27:00) [6]> [26] Курдль © (11.05.04 23:20)
скорее всего открытый запрос у него квери в гриде отображается и он не хочет целиком перезапрашивать его, имеет смысл в принципе если большая выборка и реализован эффективный механизм уведомлений об изменениях, хотя это не просто.. много холостых данных и проблема с редактированием, о чем уже говорилось
хотя при желании можно конечно сделать, проблему холостых данных можно решить через подписку на события об изменениях и отписываться в случае если юзер не работает с программой..
мое имхо лучше без этого обойтись
Курдль (2004-05-11 23:20:00) [7]
> VoVovanych © (11.05.04 21:58) [23]
> (добавить и т.д.). ЗАДАЧА: КАК В УЖЕ ОТКРЫТЫЙ ЗАПРОС ПОЛУЧИТЬ
> С СЕРВЕРА НОВЫЕ (ОБНОВЛЕННЫЕ) ДАННЫЕ? То ли лыжи у меня
> не едут, то ли одно из двух.
Вы достаточно тертый калач, но ленитесь! Для себя бы я чё-нить придумал (пока что просто таких ТЗ не попадалось) а для Вас - тоже лень :)
Ну есть идея (в предсонном бреду) создать журнал логов на значимые таблицы и "вести" в нем по триггерам изменения значимых полей. Отдельным запросом порлучать свежие данные, обрабатывать на клиенте по принципу "это у нас уже есть, а это, ты глянь, - изменилось!". А потом насильственно записывать в набор данных обработанные изменения.
И далее - давайте по понятиям! Что есть "ОТКРЫТЫЙ ЗАПРОС"? Видимо "ПОЛУЧЕННЫЙ НАБОР ДАННЫХ"?
Petr V. Abramov (2004-05-11 23:05:00) [8]CachedUpdates = true
отдельный запрос обновлений (пусть qrRefresh) по таймеру или по event`ам
ручная перекачка записей из qrRefresh в основной
возможно, еще геморрой с соблюдением сортировки
Polevi (2004-05-11 23:02:00) [9]запросить эти данные во временный датасет, ручкам пробежать по нему и обновить рабочий сет
еснно нужно ключевое поле для сопоставления записей
VoVovanych (2004-05-11 21:58:00) [10]2 Курдль: не совсем. Каждое запущенное приложение получает от сервера сообщение и запускает у себя процедуру обновления данных. Теоретически это задумывалось так :). Практически не получилось. Так и родился сабж...
2 Petr V. Abramov ©: Возможность поиска есть, причем настолько навороченная, что лучше уж по моему быть не может (просьба не изголятся по поводу навороченности, не тратьте время) :) Просто для оперативного решения вопросов необходимо видеть ВСЁ...
2 ВСЕМ: попытка №3. Отвлечемся от постановки задачи, кнопок принудительного обновления, timestampов, правильно-неправильно и т.д. Будем считать что мы знаем какие записи нужно обновить (добавить и т.д.). ЗАДАЧА: КАК В УЖЕ ОТКРЫТЫЙ ЗАПРОС ПОЛУЧИТЬ С СЕРВЕРА НОВЫЕ (ОБНОВЛЕННЫЕ) ДАННЫЕ? То ли лыжи у меня не едут, то ли одно из двух.
Anatoly Podgoretsky (2004-05-11 19:45:00) [11]VoVovanych © (11.05.04 16:32) [18]
Как считывать из базы именно добавленные или обновленные данные?
Anatoly Podgoretsky © (11.05.04 09:04) [1]
Добавить timestamp
Без временной метки это не возможно сделать, ты никак не отличишь обновленную от необновленной. Каждая запись в таблицу должна делаться с обновленной меткой, тогда в запросе можно будет указать TS>OldTS, вернутся все новые и обновленные
AGin (2004-05-11 19:23:00) [12]2 VoVovanych Мне кажется, что в Вашем случае поможет несколько извращенное решение - использовать обычные GRID'ы (НЕ DBGRID'ы) для отображения информации (или другие контролы). Тогда от пользователя будет скрыта вся внутренняя работа программы по обновлению данных. А данные следует обновлять, как советовал А.Подгорецкий (и другие) - в каждую нужную таблицу добалять поле timestamp и раз в минуту просматривать ID отредактированных за эту минуту записей. При наличии таковых - обновлять информацию в GRID'ах ВРУЧНУЮ. Это, конечно, геморрой, но не очень большрй...:))
Petr V. Abramov (2004-05-11 18:52:00) [13]> рефрешатся каждую минуту...
Либо у них нету возможностей поиска
Либо постановка задачи нехорошая
Либо это действительно надо (1% вероятности). Тогда либо event`ы, либо AppServer какой-нить масти
Курдль (2004-05-11 17:23:00) [14]Боюсь, что никакие FIBDataSet-ы с обновлением одной записи Вам не поможет, т.к. он вернет ее только Вам же, а не всем юзерам.
VoVovanych (2004-05-11 16:32:00) [15]Тпру... Стойте, остановитесь. Не думал что мой вопрос вызовет такую бурю эмоций. Тем более разбирательств "хам-нехам" :) Я возможно не совсем корректно задал вопрос: возможно ли получить в УЖЕ ОТКРЫТЫЙ запрос запись, добавленную другим пользователем, тем более что необходимость в актуальных данных имеется (привести полностью постановку задачи не могу, долго и нудно)? Пробовал использовать FIBPlus (ОГРОМНОЕ СПАСИБО Сергею БУЗАДЖИ, обещаю купить лицензионку), там есть компонент FIBDataSet и у него метод Refresh, который автоматически после вставки или удаления обновляет именно ту запись, в которой произошли изменения (естественно не на всех машинах, а на той где эти изменения и произошли :)). Кто не знаком с FIBDataSet хочу пояснить что запрос на обновление выглядит примерно так: Select X From Y Where Z=:OLD_ID (ID ключевое поле таблицы). То есть при редактировании, точнее после редактирования, вызывается этот самый запрос, в котором параметру OLD_ID присваивается значение ID той самой отредактированной записи и соответственно обновляется только эта запись. Уф-ф-ф-ф... Надеюсь понятно объяснил. Так вот, я пробовал сделать так: приложение получало от сервера сообщение о том что добавлена или изменена запись, передавался ID записи, я пытался передать этот ID в запрос как OLD_ID (примерно так qryAAA.ParamByName('OLD_ID').As Integer:=ID) и вызвать Refresh... Безрезультатно :( Получаю ошибку что-то типа "Параметр OLD_ID не существует". Как насчет такого варианта развития события?
2Sergey13 В данный момент у меня стоит кнопка "Обновить"... Многим не нравиться, да и не помогает: рефрешатся каждую минуту...
2Anatoly Podgoretsky: Часто читаю Ваши ответы и они помогают. Единственная проблема - краткие они очень :)... Если можно, разъясните несколько подробней. Разжевывать не надо, просто нарежьте :)))
Desdechado (2004-05-11 13:23:00) [16][12] Locker
гы, ладно, внес изменения, запостил, но в БД не сохранил - что здесь, а?
Danilka (2004-05-11 13:11:00) [17][12] Locker (11.05.04 12:44)
И еще, вот тебе ненадуманный пример: запрос на 12 килобайт из доброго десятка таблиц и вьюх, возвращает как-раз сотню записей (в таблицах десятки и сотни тысяч записей), ну-ка куда и чего надо добавить, чтобы получить только обновленные записи?
И добавь-ка дорогой все эти обновленные данные в грид, и только тем пользователям, кому надо (если отвернулся от монитора, значит ему не надо).
Danilka (2004-05-11 12:53:00) [18][12] Locker (11.05.04 12:44)
Гы.
Ну давай возьмем твой надуманый пример. Конктретно вопрос.
> Как другим пользователям узнать, что в БД добавлен новый
> клиент?
А нафига? Нафига им узнавать что добавлен новый клиент?
Ну заполняю я, к примеру, счет-фактуру, выбираю клиента из списка клиентов, при этом на момент выбора клиента идет запрос к серверу.
Момент времени, при котором я открываю список клиентов, ищу того, который мне нужен и выбираю его в СФ очень короткий. Даже если за этот момент и появился новый клиент - он мне по-барабану.
> Обновлять все 50000 записей (хм...)?
Вообще, тянуть столько записей на клиента - грех.
Mike Kouzmine (2004-05-11 12:53:00) [19]Locker (11.05.04 12:44) [12] А зачем им это узнавать? Добавили и добавили, слава Аллаху!
Nikolay M. (2004-05-11 12:52:00) [20]
> 2 Nikolay M.
> Объясните, почему это не нужно?
Потому что по большому счету я согласен с [2].
Тема поднималась уже раз 100, наверное. Пока было предложено единственно правильное решение - обновлять запрос по нажатию юзером кнопки. Все остальное - от лукавого.
ПС
Кстати, тут прозвучали мысли о посылке апп-сервером клиентам сообщения, что нужно обновиться. Гораздо логичнее, имхо, рассылать собственно изменения, а не заставлять кучу юзеров ломиться рефрешить свои данные. Собственно, я об этом сказал еще в [3].